/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.security.auth; import static org.junit.Assert.assertTrue; import java.lang.reflect.Constructor; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PublicKey; import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.X509Certificate; import java.text.MessageFormat; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import org.geoserver.data.test.SystemTestData; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.security.AbstractSecurityServiceTest; import org.geoserver.security.GeoServerAuthenticationProvider; import org.geoserver.security.GeoServerRoleService; import org.geoserver.security.GeoServerRoleStore; import org.geoserver.security.GeoServerSecurityFilterChain; import org.geoserver.security.GeoServerSecurityFilterChainProxy; import org.geoserver.security.GeoServerUserGroupService; import org.geoserver.security.GeoServerUserGroupStore; import org.geoserver.security.HtmlLoginFilterChain; import org.geoserver.security.RequestFilterChain; import org.geoserver.security.VariableFilterChain; import org.geoserver.security.config.SecurityManagerConfig; import org.geoserver.security.config.SecurityRoleServiceConfig; import org.geoserver.security.config.SecurityUserGroupServiceConfig; import org.geoserver.security.config.UsernamePasswordAuthenticationProviderConfig; import org.geoserver.security.config.impl.MemoryRoleServiceConfigImpl; import org.geoserver.security.config.impl.MemoryUserGroupServiceConfigImpl; import org.geoserver.security.impl.DigestAuthUtils; import org.geoserver.security.impl.GeoServerRole; import org.geoserver.security.impl.GeoServerUser; import org.geoserver.security.impl.MemoryRoleService; import org.geoserver.security.impl.MemoryUserGroupService; import org.geoserver.security.password.PasswordValidator; import org.springframework.security.core.Authentication; import org.springframework.mock.web.MockHttpServletRequest; public abstract class AbstractAuthenticationProviderTest extends AbstractSecurityServiceTest { public final static String testUserName = "user1"; public final static String testPassword = "pw1"; public final static String rootRole = "RootRole"; public final static String derivedRole = "DerivedRole"; protected String pattern = "/foo/**"; public final static String testProviderName = "testAuthenticationProvider"; @Override protected void onSetUp(SystemTestData testData) throws Exception { super.onSetUp(testData); createServices(); } @Override protected void setUpSpring(List<String> springContextLocations) { super.setUpSpring(springContextLocations); springContextLocations.add(AbstractAuthenticationProviderTest.class.getResource( AbstractAuthenticationProviderTest.class.getSimpleName() + "-context.xml").toString()); } protected TestingAuthenticationCache getCache() { return (TestingAuthenticationCache) getSecurityManager().getAuthenticationCache(); } protected void createServices() throws Exception{ GeoServerRoleService rservice = createRoleService("rs1"); GeoServerRoleStore rstore = rservice.createStore(); GeoServerRole root, derived; rstore.addRole(root=rstore.createRoleObject(rootRole)); rstore.addRole(derived=rstore.createRoleObject(derivedRole)); rstore.setParentRole(derived, root); rstore.associateRoleToUser(derived, testUserName); rstore.associateRoleToUser(derived, "castest"); rstore.store(); SecurityManagerConfig mconfig = getSecurityManager().loadSecurityConfig(); mconfig.setRoleServiceName("rs1"); getSecurityManager().saveSecurityConfig(mconfig); GeoServerUserGroupService ugservice = createUserGroupService("ug1"); GeoServerUserGroupStore ugstore = ugservice.createStore(); GeoServerUser u1 = ugstore.createUserObject(testUserName, testPassword, true); ugstore.addUser(u1); GeoServerUser u2 = ugstore.createUserObject("abc@xyz.com", "abc", true); ugstore.addUser(u2); GeoServerUser u3 = ugstore.createUserObject("castest", "castest", true); ugstore.addUser(u3); ugstore.store(); GeoServerAuthenticationProvider prov = createAuthProvider(testProviderName, ugservice.getName()); prepareAuthProviders(prov.getName()); } protected void insertAnonymousFilter() throws Exception{ SecurityManagerConfig mconfig = getSecurityManager().loadSecurityConfig(); mconfig.getFilterChain().find(pattern).getFilterNames().add(GeoServerSecurityFilterChain.ANONYMOUS_FILTER); getSecurityManager().saveSecurityConfig(mconfig); } protected void removeAnonymousFilter() throws Exception{ SecurityManagerConfig mconfig = getSecurityManager().loadSecurityConfig(); mconfig.getFilterChain().find(pattern).getFilterNames() .remove(GeoServerSecurityFilterChain.ANONYMOUS_FILTER); getSecurityManager().saveSecurityConfig(mconfig); } public GeoServerAuthenticationProvider createAuthProvider(String name, String userGroupServiceName) throws Exception { UsernamePasswordAuthenticationProviderConfig config = new UsernamePasswordAuthenticationProviderConfig(); config.setClassName(UsernamePasswordAuthenticationProvider.class.getName()); config.setUserGroupServiceName(userGroupServiceName); config.setName(name); getSecurityManager().saveAuthenticationProvider(config); return getSecurityManager().loadAuthenticationProvider(name); } @Override public GeoServerRoleService createRoleService(String name) throws Exception { SecurityRoleServiceConfig config = getRoleConfig(name); getSecurityManager().saveRoleService(config); return getSecurityManager().loadRoleService(name); } public MemoryRoleServiceConfigImpl getRoleConfig(String name) { MemoryRoleServiceConfigImpl config = new MemoryRoleServiceConfigImpl(); config.setName(name); config.setClassName(MemoryRoleService.class.getName()); config.setToBeEncrypted("encryptme"); return config; } @Override public GeoServerUserGroupService createUserGroupService(String name) throws Exception { return createUserGroupService(name, getPBEPasswordEncoder().getName()); } public GeoServerUserGroupService createUserGroupService(String name,String passwordEncoderName) throws Exception { SecurityUserGroupServiceConfig config = getUserGroupConfg(name, passwordEncoderName); getSecurityManager().saveUserGroupService(config/*,isNewUGService(name)*/); return getSecurityManager().loadUserGroupService(name); } public MemoryUserGroupServiceConfigImpl getUserGroupConfg(String name, String passwordEncoderName) { MemoryUserGroupServiceConfigImpl config = new MemoryUserGroupServiceConfigImpl(); config.setName(name); config.setClassName(MemoryUserGroupService.class.getName()); config.setPasswordEncoderName(passwordEncoderName); config.setPasswordPolicyName(PasswordValidator.DEFAULT_NAME); config.setToBeEncrypted("encryptme"); return config; } public void checkForAuthenticatedRole(Authentication auth) { assertTrue(auth.getAuthorities().contains(GeoServerRole.AUTHENTICATED_ROLE)); } protected void prepareAuthProviders(String... authProviderNames) throws Exception{ SecurityManagerConfig config = getSecurityManager().getSecurityConfig(); config.getAuthProviderNames().clear(); for (String n : authProviderNames) config.getAuthProviderNames().add(n); getSecurityManager().saveSecurityConfig(config); } protected void prepareFilterChain(Class filterChainClass, String pattern, String... filterNames) throws Exception{ SecurityManagerConfig config = getSecurityManager().getSecurityConfig(); GeoServerSecurityFilterChain filterChain = config.getFilterChain(); filterChain.removeForPattern(pattern); Constructor<?> cons = filterChainClass.getConstructor(new Class[] { String[].class }); String[] args= new String[] {pattern}; RequestFilterChain requestChain = (RequestFilterChain)cons.newInstance(new Object[] {args}); requestChain = new HtmlLoginFilterChain(pattern); requestChain.setName("testChain"); requestChain.setFilterNames(filterNames); //insert before default filterChain.getRequestChains().add(filterChain.getRequestChains().size()-2, requestChain); getSecurityManager().saveSecurityConfig(config); } protected void modifyChain(String pattern, boolean disabled,boolean allowSessionCreation,String roleFilterName) throws Exception { SecurityManagerConfig config = getSecurityManager().getSecurityConfig(); RequestFilterChain chain = config.getFilterChain().find(pattern); chain.setDisabled(disabled); chain.setAllowSessionCreation(allowSessionCreation); chain.setRoleFilterName(roleFilterName); getSecurityManager().saveSecurityConfig(config); return; } protected void prepareFilterChain(String pattern, String... filterNames) throws Exception{ prepareFilterChain(HtmlLoginFilterChain.class,pattern, filterNames); } protected void updateUser(String ugService, String userName,boolean enabled) throws Exception { GeoServerUserGroupService ugservice = getSecurityManager().loadUserGroupService(ugService); GeoServerUserGroupStore ugstore = ugservice.createStore(); GeoServerUser u1 = ugstore.getUserByUsername(userName); u1.setEnabled(enabled); ugstore.updateUser(u1); ugstore.store(); } protected GeoServerSecurityFilterChainProxy getProxy() { return GeoServerExtensions.bean(GeoServerSecurityFilterChainProxy.class); } protected String clientDigestString(String serverDigestString, String username, String password, String method) { String section212response = serverDigestString.substring(7); String[] headerEntries = DigestAuthUtils.splitIgnoringQuotes(section212response, ','); Map<String,String> headerMap = DigestAuthUtils.splitEachArrayElementAndCreateMap(headerEntries, "=", "\""); String realm = headerMap.get("realm"); String qop= headerMap.get("qop"); String nonce= headerMap.get("nonce"); String uri="/foo/bar"; String nc="00000001"; String cnonce="0a4f113b"; String opaque="5ccc069c403ebaf9f0171e9517f40e41"; String responseString = DigestAuthUtils.generateDigest( false, username, realm, password, method, uri, qop, nonce, nc, cnonce); String template = "Digest username=\"{0}\",realm=\"{1}\""; template+=",nonce=\"{2}\",uri=\"{3}\""; template+=",qop=\"{4}\",nc=\"{5}\""; template+=",cnonce=\"{6}\",response=\"{7}\""; template+=",opaque=\"{8}\""; return MessageFormat.format(template, username,realm,nonce,uri,qop,nc,cnonce,responseString,opaque); } protected void setCertifacteForUser(final String userName, MockHttpServletRequest request) { X509Certificate x509 = new X509Certificate() { @Override public Set<String> getCriticalExtensionOIDs() { return null; } @Override public byte[] getExtensionValue(String arg0) { return null; } @Override public Set<String> getNonCriticalExtensionOIDs() { return null; } @Override public boolean hasUnsupportedCriticalExtension() { return false; } @Override public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { } @Override public void checkValidity(Date arg0) throws CertificateExpiredException, CertificateNotYetValidException { } @Override public int getBasicConstraints() { return 0; } @Override public Principal getIssuerDN() { return null; } @Override public boolean[] getIssuerUniqueID() { return null; } @Override public boolean[] getKeyUsage() { return null; } @Override public Date getNotAfter() { return null; } @Override public Date getNotBefore() { return null; } @Override public BigInteger getSerialNumber() { return null; } @Override public String getSigAlgName() { return null; } @Override public String getSigAlgOID() { return null; } @Override public byte[] getSigAlgParams() { return null; } @Override public byte[] getSignature() { return null; } @Override public Principal getSubjectDN() { return new Principal () { @Override public String getName() { return "cn="+userName+",ou=ou1"; } }; } @Override public boolean[] getSubjectUniqueID() { return null; } @Override public byte[] getTBSCertificate() throws CertificateEncodingException { return null; } @Override public int getVersion() { return 0; } @Override public byte[] getEncoded() throws CertificateEncodingException { return null; } @Override public PublicKey getPublicKey() { return null; } @Override public String toString() { return null; } @Override public void verify(PublicKey arg0) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { } @Override public void verify(PublicKey arg0, String arg1) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { } }; request.setAttribute("javax.servlet.request.X509Certificate", new X509Certificate[]{x509}); } // @Override // protected MockHttpServletRequest createRequest(String path) { // MockHttpServletRequest req= super.createRequest(path); // req.setServletPath(""); // req.setPathInfo(path); // return req; // // } }