/* (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.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.net.URLEncoder;
import java.security.Principal;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.security.ConstantFilterChain;
import org.geoserver.security.GeoServerSecurityFilterChain;
import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.RequestFilterChain;
import org.geoserver.security.config.BasicAuthenticationFilterConfig;
import org.geoserver.security.config.CredentialsFromRequestHeaderFilterConfig;
import org.geoserver.security.config.DigestAuthenticationFilterConfig;
import org.geoserver.security.config.J2eeAuthenticationBaseFilterConfig;
import org.geoserver.security.config.J2eeAuthenticationBaseFilterConfig.J2EERoleSource;
import org.geoserver.security.config.J2eeAuthenticationFilterConfig;
import org.geoserver.security.config.LogoutFilterConfig;
import org.geoserver.security.config.PreAuthenticatedUserNameFilterConfig.PreAuthenticatedUserNameRoleSource;
import org.geoserver.security.config.RequestHeaderAuthenticationFilterConfig;
import org.geoserver.security.config.SecurityFilterConfig;
import org.geoserver.security.config.SecurityManagerConfig;
import org.geoserver.security.config.UsernamePasswordAuthenticationFilterConfig;
import org.geoserver.security.config.X509CertificateAuthenticationFilterConfig;
import org.geoserver.security.filter.GeoServerBasicAuthenticationFilter;
import org.geoserver.security.filter.GeoServerCredentialsFromRequestHeaderFilter;
import org.geoserver.security.filter.GeoServerDigestAuthenticationFilter;
import org.geoserver.security.filter.GeoServerJ2eeAuthenticationFilter;
import org.geoserver.security.filter.GeoServerLogoutFilter;
import org.geoserver.security.filter.GeoServerRequestHeaderAuthenticationFilter;
import org.geoserver.security.filter.GeoServerRoleFilter;
import org.geoserver.security.filter.GeoServerUserNamePasswordAuthenticationFilter;
import org.geoserver.security.filter.GeoServerX509CertificateAuthenticationFilter;
import org.geoserver.security.impl.GeoServerRole;
import org.geoserver.security.impl.GeoServerUser;
import org.geoserver.test.RunTestSetup;
import org.geoserver.test.SystemTest;
import org.geotools.data.Base64;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@Category(SystemTest.class)
public class AuthenticationFilterTest extends AbstractAuthenticationProviderTest {
public final static String testFilterName = "basicAuthTestFilter";
public final static String testFilterName2 = "digestAuthTestFilter";
public final static String testFilterName3 = "j2eeAuthTestFilter";
public final static String testFilterName4 = "requestHeaderTestFilter";
public final static String testFilterName5 = "basicAuthTestFilterWithRememberMe";
public final static String testFilterName6 = "formLoginTestFilter";
public final static String testFilterName7 = "formLoginTestFilterWithRememberMe";
public final static String testFilterName8 = "x509TestFilter";
public final static String testFilterName9 = "logoutTestFilter";
public final static String testFilterName10 = "credentialsFromHeaderTestFilter";
@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
LogoutFilterConfig loConfig = new LogoutFilterConfig();
loConfig.setClassName(GeoServerLogoutFilter.class.getName());
loConfig.setName(testFilterName9);
loConfig.setRedirectURL(GeoServerLogoutFilter.URL_AFTER_LOGOUT);
getSecurityManager().saveFilter(loConfig);
BasicAuthenticationFilterConfig bconfig = new BasicAuthenticationFilterConfig();
bconfig.setClassName(GeoServerBasicAuthenticationFilter.class.getName());
bconfig.setUseRememberMe(false);
bconfig.setName(testFilterName);
getSecurityManager().saveFilter(bconfig);
}
@Before
public void revertFilters() throws Exception {
GeoServerSecurityManager secMgr = getSecurityManager();
if (secMgr.listFilters().contains(testFilterName2)) {
SecurityFilterConfig config = secMgr.loadFilterConfig(testFilterName2);
secMgr.removeFilter(config);
}
}
@Test
public void testBasicAuth() throws Exception{
// BasicAuthenticationFilterConfig config = new BasicAuthenticationFilterConfig();
// config.setClassName(GeoServerBasicAuthenticationFilter.class.getName());
// config.setUseRememberMe(false);
// config.setName(testFilterName);
// getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName);
modifyChain(pattern, false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
String tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Basic") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
modifyChain(pattern, false, true,GeoServerSecurityFilterChain.ROLE_FILTER);
// check success
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes((testUserName+":"+testPassword).getBytes())));
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
String roleString=response.getHeader(GeoServerRoleFilter.DEFAULT_HEADER_ATTRIBUTE);
assertNotNull(roleString);
String[] roles = roleString.split(";");
assertEquals(3, roles.length);
List<String> roleList = Arrays.asList(roles);
assertTrue(roleList.contains(GeoServerRole.AUTHENTICATED_ROLE.getAuthority()));
assertTrue(roleList.contains(rootRole));
assertTrue(roleList.contains(derivedRole));
// check wrong password
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes((testUserName+":wrongpass").getBytes())));
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Basic") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check unknown user
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes(("unknwon:"+testPassword).getBytes())));
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Basic") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check root user
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes((GeoServerUser.ROOT_USERNAME+":"+getMasterPassword()).getBytes())));
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
//checkForAuthenticatedRole(auth);
assertEquals(GeoServerUser.ROOT_USERNAME, auth.getPrincipal());
assertTrue(auth.getAuthorities().size()==1);
assertTrue(auth.getAuthorities().contains(GeoServerRole.ADMIN_ROLE));
// check root user with wrong password
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes((GeoServerUser.ROOT_USERNAME+":geoserver1").getBytes())));
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Basic") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check disabled user, clear cache first
getSecurityManager().getAuthenticationCache().removeAll();
updateUser("ug1", testUserName, false);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes((testUserName+":"+testPassword).getBytes())));
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Basic") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
updateUser("ug1", testUserName, true);
// Test anonymous
insertAnonymousFilter();
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
// Anonymous context is not stored in http session, no further testing
removeAnonymousFilter();
}
@Test
public void testCredentialsFromHeader() throws Exception {
CredentialsFromRequestHeaderFilterConfig config = new CredentialsFromRequestHeaderFilterConfig();
config.setClassName(GeoServerCredentialsFromRequestHeaderFilter.class.getName());
config.setUserNameHeaderName("X-Credentials");
config.setPasswordHeaderName("X-Credentials");
config.setUserNameRegex("private-user=([^&]*)");
config.setPasswordRegex("private-pw=([^&]*)");
config.setParseAsUriComponents(true);
config.setName(testFilterName10);
getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName10);
modifyChain(pattern, false, true,null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus());
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check success
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("X-Credentials", "private-user="+testUserName+"&private-pw="+testPassword);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
// check wrong password
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("X-Credentials", "private-user="+testUserName+"&private-pw=wrongpass");
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check unknown user
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("X-Credentials", "private-user=wronguser&private-pw="+testPassword);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check root user
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
String masterPassword = URLEncoder.encode(getMasterPassword(), "UTF-8");
request.addHeader("X-Credentials", "private-user="+GeoServerUser.ROOT_USERNAME+"&private-pw=" + masterPassword);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
//checkForAuthenticatedRole(auth);
assertEquals(GeoServerUser.ROOT_USERNAME, auth.getPrincipal());
assertTrue(auth.getAuthorities().size()==2);
assertTrue(auth.getAuthorities().contains(GeoServerRole.ADMIN_ROLE));
// check root user with wrong password
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("X-Credentials", "private-user="+GeoServerUser.ROOT_USERNAME+"&private-pw=geoserver1");
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check disabled user, clear cache first
getSecurityManager().getAuthenticationCache().removeAll();
updateUser("ug1", testUserName, false);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("X-Credentials", "private-user="+testUserName+"&private-pw="+testPassword);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
updateUser("ug1", testUserName, true);
// Test anonymous
insertAnonymousFilter();
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
// Anonymous context is not stored in http session, no further testing
removeAnonymousFilter();
}
@Test
public void testJ2eeProxy() throws Exception{
J2eeAuthenticationFilterConfig config = new J2eeAuthenticationFilterConfig();
config.setClassName(GeoServerJ2eeAuthenticationFilter.class.getName());
config.setName(testFilterName3);
config.setRoleSource(J2EERoleSource.J2EE);
config.setRoleServiceName("rs1");
config.setUserGroupServiceName("ug1");
config.setRolesHeaderAttribute("roles");
getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName3);
modifyChain(pattern, false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus());
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
Authentication auth;
for(J2EERoleSource rs : J2eeAuthenticationBaseFilterConfig.J2EERoleSource.values()) {
config.setRoleSource(rs);
getSecurityManager().saveFilter(config);
// test preauthenticated with various role sources
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setUserPrincipal(new Principal() {
@Override
public String getName() {
return testUserName;
}
});
if (rs==J2EERoleSource.Header) {
request.addHeader("roles", derivedRole+";"+rootRole);
}
if(rs==J2EERoleSource.J2EE) {
if(true) {
request.addUserRole(derivedRole);
}
if(false) {
request.addUserRole(rootRole);
}
}
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, auth.getPrincipal());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
}
// test root
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setUserPrincipal(new Principal() {
@Override
public String getName() {
return GeoServerUser.ROOT_USERNAME;
}
});
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
//checkForAuthenticatedRole(auth);
assertEquals(GeoServerUser.ROOT_USERNAME, auth.getPrincipal());
assertTrue(auth.getAuthorities().size()==1);
assertTrue(auth.getAuthorities().contains(GeoServerRole.ADMIN_ROLE));
config.setRoleServiceName(null);
getSecurityManager().saveFilter(config);
// test preauthenticated with active role service
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setUserPrincipal(new Principal() {
@Override
public String getName() {
return testUserName;
}
});
if(true) {
request.addUserRole(derivedRole);
}
if(false) {
request.addUserRole(rootRole);
}
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth=ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, auth.getPrincipal());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
// Test anonymous
insertAnonymousFilter();
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
// Anonymous context is not stored in http session, no further testing
removeAnonymousFilter();
}
@Test
public void testRequestHeaderProxy() throws Exception{
RequestHeaderAuthenticationFilterConfig config =
new RequestHeaderAuthenticationFilterConfig();
config.setClassName(GeoServerRequestHeaderAuthenticationFilter.class.getName());
config.setName(testFilterName4);
config.setRoleServiceName("rs1");
config.setPrincipalHeaderAttribute("principal");
config.setRoleSource(PreAuthenticatedUserNameRoleSource.RoleService);
config.setUserGroupServiceName("ug1");
config.setPrincipalHeaderAttribute("principal");
config.setRolesHeaderAttribute("roles");;
getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName4);
modifyChain(pattern, false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus());
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
for (PreAuthenticatedUserNameRoleSource rs : PreAuthenticatedUserNameRoleSource.values()) {
config.setRoleSource(rs);
getSecurityManager().saveFilter(config);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("principal", testUserName);
if (rs.equals(PreAuthenticatedUserNameRoleSource.Header)) {
request.addHeader("roles", derivedRole+";"+rootRole);
}
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, auth.getPrincipal());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
}
// unknown user
for (PreAuthenticatedUserNameRoleSource rs : PreAuthenticatedUserNameRoleSource.values()) {
config.setRoleSource(rs);
getSecurityManager().saveFilter(config);
config.setRoleSource(rs);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("principal", "unknwon");
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals("unknwon", auth.getPrincipal());
}
// test disabled user
updateUser("ug1", testUserName, false);
config.setRoleSource(PreAuthenticatedUserNameRoleSource.UserGroupService);
getSecurityManager().saveFilter(config);
request= createRequest("/foo/bar");
request.addHeader("principal", testUserName);
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
updateUser("ug1", testUserName, true);
// Test anonymous
insertAnonymousFilter();
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
// Anonymous context is not stored in http session, no further testing
removeAnonymousFilter();
}
@Test
public void testDigestAuth() throws Exception{
DigestAuthenticationFilterConfig config = new DigestAuthenticationFilterConfig();
config.setClassName(GeoServerDigestAuthenticationFilter.class.getName());
config.setName(testFilterName2);
config.setUserGroupServiceName("ug1");
getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName2);
modifyChain(pattern, false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_UNAUTHORIZED,response.getStatus());
String tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Digest") !=-1 );
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// test successful login
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
String headerValue=clientDigestString(tmp, testUserName, testPassword, request.getMethod());
request.addHeader("Authorization", headerValue);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
// check wrong password
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
headerValue=clientDigestString(tmp, testUserName, "wrongpass", request.getMethod());
request.addHeader("Authorization", headerValue);
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Digest") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check unknown user
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
headerValue=clientDigestString(tmp, "unknown", testPassword, request.getMethod());
request.addHeader("Authorization", headerValue);
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Digest") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check root user
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
headerValue=clientDigestString(tmp, GeoServerUser.ROOT_USERNAME, getMasterPassword(), request.getMethod());
request.addHeader("Authorization", headerValue);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
//checkForAuthenticatedRole(auth);
assertEquals(GeoServerUser.ROOT_USERNAME, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().size()==1);
assertTrue(auth.getAuthorities().contains(GeoServerRole.ADMIN_ROLE));
// check root user with wrong password
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
headerValue=clientDigestString(tmp, GeoServerUser.ROOT_USERNAME, "geoserver1", request.getMethod());
request.addHeader("Authorization", headerValue);
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Digest") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check disabled user
updateUser("ug1", testUserName, false);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
headerValue=clientDigestString(tmp, "unknown", testPassword, request.getMethod());
request.addHeader("Authorization", headerValue);
getProxy().doFilter(request, response, chain);
tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Digest") !=-1 );
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
updateUser("ug1", testUserName, true);
// Test anonymous
insertAnonymousFilter();
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
// Anonymous context is not stored in http session, no further testing
removeAnonymousFilter();
}
@Test
public void testBasicAuthWithRememberMe() throws Exception{
BasicAuthenticationFilterConfig config = new BasicAuthenticationFilterConfig();
config.setClassName(GeoServerBasicAuthenticationFilter.class.getName());
config.setUseRememberMe(true);
config.setName(testFilterName5);
getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName5,
GeoServerSecurityFilterChain.REMEMBER_ME_FILTER);
modifyChain(pattern, false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
request.addParameter("_spring_security_remember_me", "yes");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(0, response.getCookies().length);
String tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
// check success
request= createRequest("/foo/bar");
request.addParameter("_spring_security_remember_me", "yes");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes(("abc@xyz.com:abc").getBytes())));
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(1,response.getCookies().length);
Cookie cookie = (Cookie) response.getCookies()[0];
request= createRequest("/foo/bar");
request.addParameter("_spring_security_remember_me", "yes");
request.setCookies(cookie);
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals("abc@xyz.com", ((UserDetails) auth.getPrincipal()).getUsername());
// assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
// assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
// send cookie + auth header
request= createRequest("/foo/bar");
request.addParameter("_spring_security_remember_me", "yes");
request.setCookies(cookie);
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes(("abc@xyz.com:abc").getBytes())));
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals("abc@xyz.com", ((UserDetails) auth.getPrincipal()).getUsername());
// check no remember me for root user
request= createRequest("/foo/bar");
request.addParameter("_spring_security_remember_me", "yes");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes((GeoServerUser.ROOT_USERNAME+":"+getMasterPassword()).getBytes())));
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
//checkForAuthenticatedRole(auth);
// no cookie for root user
assertEquals(0,response.getCookies().length);
// check disabled user
updateUser("ug1", "abc@xyz.com", false);
request= createRequest("/foo/bar");
request.addParameter("_spring_security_remember_me", "yes");
request.setCookies(cookie);
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
// check for cancel cookie
assertEquals(1,response.getCookies().length);
Cookie cancelCookie = (Cookie) response.getCookies()[0];
assertNull(cancelCookie.getValue());
updateUser("ug1", "abc@xyz.com", true);
}
@Test
public void testFormLogin() throws Exception {
UsernamePasswordAuthenticationFilterConfig config = new UsernamePasswordAuthenticationFilterConfig();
config.setClassName(GeoServerUserNamePasswordAuthenticationFilter.class.getName());
config.setUsernameParameterName("username");
config.setPasswordParameterName("password");
config.setName(testFilterName6);
getSecurityManager().saveFilter(config);
// LogoutFilterConfig loConfig = new LogoutFilterConfig();
// loConfig.setClassName(GeoServerLogoutFilter.class.getName());
// loConfig.setName(testFilterName9);
// getSecurityManager().saveFilter(loConfig);
prepareFilterChain(pattern,
GeoServerSecurityFilterChain.FORM_LOGIN_FILTER);
modifyChain(pattern, false, true,null);
prepareFilterChain(ConstantFilterChain.class,"/j_spring_security_check_foo/",
testFilterName6);
modifyChain("/j_spring_security_check_foo/", false, true,null);
// prepareFilterChain(LogoutFilterChain.class,"/j_spring_security_logout_foo",
// GeoServerSecurityFilterChain.SECURITY_CONTEXT_ASC_FILTER,
// testFilterName9);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
String tmp = response.getHeader("Location");
assertTrue(tmp.endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_FORM));
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check success
request= createRequest("/j_spring_security_check_foo");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), testUserName);
request.addParameter(config.getPasswordParameterName(), testPassword);
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_SUCCCESS));
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
// Test logout
GeoServerLogoutFilter logoutFilter= (GeoServerLogoutFilter) getSecurityManager().loadFilter(GeoServerSecurityFilterChain.FORM_LOGOUT_FILTER);
request= createRequest("/j_spring_security_logout_foo");
HttpSession session = request.getSession(true);
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, ctx);
SecurityContextHolder.getContext().setAuthentication(auth);
response= new MockHttpServletResponse();
chain = new MockFilterChain();
//getProxy().doFilter(request, response, chain);
logoutFilter.doFilter(request, response,chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
tmp = response.getHeader("Location");
assertNotNull(tmp);
assertTrue(tmp.endsWith(GeoServerLogoutFilter.URL_AFTER_LOGOUT));
assertNull(SecurityContextHolder.getContext().getAuthentication());
// test invalid password
request= createRequest("/j_spring_security_check_foo");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), testUserName);
request.addParameter(config.getPasswordParameterName(), "wrongpass");
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_FAILURE));
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check unknown user
request= createRequest("/j_spring_security_check_foo");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), "unknwon");
request.addParameter(config.getPasswordParameterName(), testPassword);
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_FAILURE));
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check root user
request= createRequest("/j_spring_security_check_foo");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), GeoServerUser.ROOT_USERNAME);
request.addParameter(config.getPasswordParameterName(), getMasterPassword());
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_SUCCCESS));
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
//checkForAuthenticatedRole(auth);
assertEquals(GeoServerUser.ROOT_USERNAME, auth.getPrincipal());
assertTrue(auth.getAuthorities().size()==1);
assertTrue(auth.getAuthorities().contains(GeoServerRole.ADMIN_ROLE));
// check root user with wrong password
request= createRequest("/j_spring_security_check_foo");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), GeoServerUser.ROOT_USERNAME);
request.addParameter(config.getPasswordParameterName(), "geoserver1");
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_FAILURE));
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// check disabled user
updateUser("ug1", testUserName, false);
request= createRequest("/j_spring_security_check_foo");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), testUserName);
request.addParameter(config.getPasswordParameterName(), testPassword);
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_FAILURE));
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
updateUser("ug1", testUserName, true);
// Test anonymous
insertAnonymousFilter();
request= createRequest("foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
// Anonymous context is not stored in http session, no further testing
removeAnonymousFilter();
}
@Test
public void testFormLoginWithRememberMe() throws Exception{
UsernamePasswordAuthenticationFilterConfig config = new UsernamePasswordAuthenticationFilterConfig();
config.setClassName(GeoServerUserNamePasswordAuthenticationFilter.class.getName());
config.setUsernameParameterName("username");
config.setPasswordParameterName("password");
config.setName(testFilterName7);
getSecurityManager().saveFilter(config);
// LogoutFilterConfig loConfig = new LogoutFilterConfig();
// loConfig.setClassName(GeoServerLogoutFilter.class.getName());
// loConfig.setName(testFilterName9);
// getSecurityManager().saveFilter(loConfig);
prepareFilterChain(pattern,
GeoServerSecurityFilterChain.REMEMBER_ME_FILTER,
GeoServerSecurityFilterChain.FORM_LOGIN_FILTER);
modifyChain(pattern, false, true,null);
prepareFilterChain("/j_spring_security_check_foo/",
testFilterName7);
modifyChain("/j_spring_security_check_foo/", false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
request.addParameter("_spring_security_remember_me", "yes");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
String tmp = response.getHeader("Location");
assertTrue(tmp.endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_FORM));
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
//check success
request= createRequest("/j_spring_security_check_foo");
request.addParameter("_spring_security_remember_me", "yes");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), testUserName);
request.addParameter(config.getPasswordParameterName(), testPassword);
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_SUCCCESS));
HttpSession session = request.getSession(true);
ctx = (SecurityContext)session.getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
assertEquals(1,response.getCookies().length);
Cookie cookie = (Cookie) response.getCookies()[0];
assertNotNull(cookie.getValue());
// check logout
GeoServerLogoutFilter logoutFilter= (GeoServerLogoutFilter) getSecurityManager().loadFilter(GeoServerSecurityFilterChain.FORM_LOGOUT_FILTER);
request= createRequest("/j_spring_security_logout_foo");
session = request.getSession(true);
session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, ctx);
SecurityContextHolder.getContext().setAuthentication(auth);
response= new MockHttpServletResponse();
chain = new MockFilterChain();
//getProxy().doFilter(request, response, chain);
logoutFilter.doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
tmp = response.getHeader("Location");
assertNotNull(tmp);
assertTrue(tmp.endsWith(GeoServerLogoutFilter.URL_AFTER_LOGOUT));
assertNull(SecurityContextHolder.getContext().getAuthentication());
Cookie cancelCookie = (Cookie) response.getCookies()[0];
assertNull(cancelCookie.getValue());
// check no remember me for root user
request= createRequest("/j_spring_security_check_foo");
request.addParameter("_spring_security_remember_me", "yes");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.setMethod("POST");
request.addParameter(config.getUsernameParameterName(), GeoServerUser.ROOT_USERNAME);
request.addParameter(config.getPasswordParameterName(), getMasterPassword());
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
assertTrue(response.getHeader("Location").endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_SUCCCESS));
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth = ctx.getAuthentication();
assertNotNull(auth);
//checkForAuthenticatedRole(auth);
assertEquals(GeoServerUser.ROOT_USERNAME,auth.getPrincipal());
assertEquals(0,response.getCookies().length);
// check disabled user
updateUser("ug1", testUserName, false);
request= createRequest("/foo/bar");
request.setCookies(cookie);
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
tmp = response.getHeader("Location");
assertTrue(tmp.endsWith(GeoServerUserNamePasswordAuthenticationFilter.URL_LOGIN_FORM));
// check for cancel cookie
assertEquals(1,response.getCookies().length);
cancelCookie = (Cookie) response.getCookies()[0];
assertNull(cancelCookie.getValue());
updateUser("ug1", testUserName, true);
}
@Test
public void testX509Auth() throws Exception{
X509CertificateAuthenticationFilterConfig config =
new X509CertificateAuthenticationFilterConfig();
config.setClassName(GeoServerX509CertificateAuthenticationFilter.class.getName());
config.setName(testFilterName8);
config.setRoleServiceName("rs1");
config.setRoleSource(org.geoserver.security.config.X509CertificateAuthenticationFilterConfig.J2EERoleSource.RoleService);
config.setUserGroupServiceName("ug1");
config.setRolesHeaderAttribute("roles");
getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName8);
modifyChain(pattern, false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus());
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
for (org.geoserver.security.config.X509CertificateAuthenticationFilterConfig.J2EERoleSource rs :
org.geoserver.security.config.X509CertificateAuthenticationFilterConfig.J2EERoleSource.values()) {
config.setRoleSource(rs);
getSecurityManager().saveFilter(config);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
if (rs==J2EERoleSource.Header) {
request.addHeader("roles", derivedRole+";"+rootRole);
}
if(rs==J2EERoleSource.J2EE) {
if(true) {
request.addUserRole(derivedRole);
}
if(false) {
request.addUserRole(rootRole);
}
}
setCertifacteForUser(testUserName, request);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, auth.getPrincipal());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
}
// unknown user
for (org.geoserver.security.config.X509CertificateAuthenticationFilterConfig.J2EERoleSource rs :
org.geoserver.security.config.X509CertificateAuthenticationFilterConfig.J2EERoleSource.values()) {
config.setRoleSource(rs);
getSecurityManager().saveFilter(config);
config.setRoleSource(rs);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
if(rs==J2EERoleSource.J2EE) {
if(false) {
request.addUserRole(derivedRole);
}
if(false) {
request.addUserRole(rootRole);
}
}
//TODO
setCertifacteForUser("unknown", request);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals("unknown", auth.getPrincipal());
}
// test disabled user
updateUser("ug1", testUserName, false);
config.setRoleSource(org.geoserver.security.config.X509CertificateAuthenticationFilterConfig.J2EERoleSource.UserGroupService);
getSecurityManager().saveFilter(config);
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
setCertifacteForUser(testUserName, request);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_FORBIDDEN,response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
updateUser("ug1", testUserName, true);
// Test anonymous
insertAnonymousFilter();
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
// Anonymous context is not stored in http session, no further testing
removeAnonymousFilter();
}
@Test
@RunTestSetup
public void testCascadingFilters() throws Exception{
// BasicAuthenticationFilterConfig bconfig = new BasicAuthenticationFilterConfig();
// bconfig.setClassName(GeoServerBasicAuthenticationFilter.class.getName());
// bconfig.setUseRememberMe(false);
// bconfig.setName(testFilterName);
// getSecurityManager().saveFilter(bconfig);
DigestAuthenticationFilterConfig config = new DigestAuthenticationFilterConfig();
config.setClassName(GeoServerDigestAuthenticationFilter.class.getName());
config.setName(testFilterName2);
config.setUserGroupServiceName("ug1");
getSecurityManager().saveFilter(config);
prepareFilterChain(pattern,
testFilterName,
testFilterName2);
modifyChain(pattern, false, true,null);
SecurityContextHolder.getContext().setAuthentication(null);
// Test entry point, must be digest
MockHttpServletRequest request= createRequest("/foo/bar");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain chain = new MockFilterChain();
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_UNAUTHORIZED,response.getStatus());
String tmp = response.getHeader("WWW-Authenticate");
assertNotNull(tmp);
assert(tmp.indexOf(GeoServerSecurityManager.REALM) !=-1 );
assert(tmp.indexOf("Digest") !=-1 );
SecurityContext ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNull(ctx);
assertNull(SecurityContextHolder.getContext().getAuthentication());
// test successful login for digest
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
String headerValue=clientDigestString(tmp, testUserName, testPassword, request.getMethod());
request.addHeader("Authorization", headerValue);
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
Authentication auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
// check success for basic authentication
request= createRequest("/foo/bar");
response= new MockHttpServletResponse();
chain = new MockFilterChain();
request.addHeader("Authorization", "Basic " +
new String(Base64.encodeBytes((testUserName+":"+testPassword).getBytes())));
getProxy().doFilter(request, response, chain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
ctx = (SecurityContext)request.getSession(true).getAttribute(
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
assertNotNull(ctx);
auth = ctx.getAuthentication();
assertNotNull(auth);
assertNull(SecurityContextHolder.getContext().getAuthentication());
checkForAuthenticatedRole(auth);
assertEquals(testUserName, ((UserDetails) auth.getPrincipal()).getUsername());
assertTrue(auth.getAuthorities().contains(new GeoServerRole(rootRole)));
assertTrue(auth.getAuthorities().contains(new GeoServerRole(derivedRole)));
}
//@Test disabled, builds locally but not onmaster
public void testSSL() throws Exception {
prepareFilterChain(pattern,GeoServerSecurityFilterChain.ANONYMOUS_FILTER);
modifyChain(pattern, false, true, null);
SecurityManagerConfig secConfig = getSecurityManager().getSecurityConfig();
RequestFilterChain chain = secConfig.getFilterChain().getRequestChainByName("testChain");
chain.setRequireSSL(true);
getSecurityManager().saveSecurityConfig(secConfig);
MockHttpServletRequest request= createRequest("/foo/bar?request=getCapabilities&a=b");
request.setProtocol("https");
MockHttpServletResponse response= new MockHttpServletResponse();
MockFilterChain authchain = new MockFilterChain();
getProxy().doFilter(request, response, authchain);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
request= createRequest("/foo/bar?request=getCapabilities&a=b");
response= new MockHttpServletResponse();
authchain = new MockFilterChain();
getProxy().doFilter(request, response, authchain);
assertTrue(response.getStatus() == MockHttpServletResponse.SC_MOVED_TEMPORARILY);
String urlString = response.getHeader("Location");
assertNotNull(urlString);
assertTrue(urlString.startsWith("https"));
assertTrue(urlString.indexOf("a=b")!=-1);
assertTrue(urlString.indexOf("443")!=-1);
chain.setRequireSSL(false);
getSecurityManager().saveSecurityConfig(secConfig);
}
}