405533 Implement special role ** for security constraints

This commit is contained in:
Jan Bartel 2013-04-19 15:53:00 +10:00
parent a7073d05a6
commit 87d4690462
13 changed files with 246 additions and 125 deletions

View File

@ -58,7 +58,6 @@ public class SecuredHelloHandler
security.setConstraintMappings(Collections.singletonList(mapping), knownRoles); security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator()); security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService); security.setLoginService(loginService);
security.setStrict(false);
HelloHandler hh = new HelloHandler(); HelloHandler hh = new HelloHandler();

View File

@ -128,12 +128,6 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
protected Constraint makeConstraint (Class servlet, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport) protected Constraint makeConstraint (Class servlet, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport)
{ {
return ConstraintSecurityHandler.createConstraint(servlet.getName(), rolesAllowed, permitOrDeny, transport); return ConstraintSecurityHandler.createConstraint(servlet.getName(), rolesAllowed, permitOrDeny, transport);
} }

View File

@ -81,7 +81,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
constraint.setAuthenticate(true); constraint.setAuthenticate(true);
constraint.setRoles(new String[]{"*"}); constraint.setRoles(new String[]{"**"}); //allow any authenticated user
ConstraintMapping mapping = new ConstraintMapping(); ConstraintMapping mapping = new ConstraintMapping();
mapping.setPathSpec("/secure"); mapping.setPathSpec("/secure");
mapping.setConstraint(constraint); mapping.setConstraint(constraint);
@ -89,7 +89,6 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
securityHandler.addConstraintMapping(mapping); securityHandler.addConstraintMapping(mapping);
securityHandler.setAuthenticator(authenticator); securityHandler.setAuthenticator(authenticator);
securityHandler.setLoginService(loginService); securityHandler.setLoginService(loginService);
securityHandler.setStrict(false);
securityHandler.setHandler(handler); securityHandler.setHandler(handler);
start(securityHandler); start(securityHandler);

View File

@ -0,0 +1,95 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.security;
import java.util.Set;
import org.eclipse.jetty.server.Authentication.User;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.UserIdentity.Scope;
/**
* AbstractUserAuthentication
*
*
* Base class for representing an authenticated user.
*/
public abstract class AbstractUserAuthentication implements User
{
protected String _method;
protected UserIdentity _userIdentity;
public AbstractUserAuthentication(String method, UserIdentity userIdentity)
{
_method = method;
_userIdentity = userIdentity;
}
@Override
public String getAuthMethod()
{
return _method;
}
@Override
public UserIdentity getUserIdentity()
{
return _userIdentity;
}
@Override
public boolean isUserInRole(Scope scope, String role)
{
String roleToTest = null;
if (scope!=null && scope.getRoleRefMap()!=null)
roleToTest=scope.getRoleRefMap().get(role);
if (roleToTest==null)
roleToTest=role;
//Servlet Spec 3.1 pg 125 if testing special role **
if ("**".equals(roleToTest.trim()))
{
//if ** is NOT a declared role name, the we return true
//as the user is authenticated. If ** HAS been declared as a
//role name, then we have to check if the user has that role
if (!declaredRolesContains("**"))
return true;
else
return _userIdentity.isUserInRole(role, scope);
}
return _userIdentity.isUserInRole(role, scope);
}
public boolean declaredRolesContains(String roleName)
{
SecurityHandler security=SecurityHandler.getCurrentSecurityHandler();
if (security==null)
return false;
if (security instanceof ConstraintAware)
{
Set<String> declaredRoles = ((ConstraintAware)security).getRoles();
return (declaredRoles != null) && declaredRoles.contains(roleName);
}
return false;
}
}

View File

@ -49,8 +49,10 @@ import org.eclipse.jetty.util.security.Constraint;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* ConstraintSecurityHandler
*
* Handler to enforce SecurityConstraints. This implementation is servlet spec * Handler to enforce SecurityConstraints. This implementation is servlet spec
* 3.0 compliant and pre-computes the constraint combinations for runtime * 3.1 compliant and pre-computes the constraint combinations for runtime
* efficiency. * efficiency.
* *
*/ */
@ -61,7 +63,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
private final List<ConstraintMapping> _constraintMappings= new CopyOnWriteArrayList<>(); private final List<ConstraintMapping> _constraintMappings= new CopyOnWriteArrayList<>();
private final Set<String> _roles = new CopyOnWriteArraySet<>(); private final Set<String> _roles = new CopyOnWriteArraySet<>();
private final PathMap<Map<String, RoleInfo>> _constraintMap = new PathMap<>(); private final PathMap<Map<String, RoleInfo>> _constraintMap = new PathMap<>();
private boolean _strict = true;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -268,36 +270,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
} }
/* ------------------------------------------------------------ */
/** Get the strict mode.
* @return true if the security handler is running in strict mode.
*/
public boolean isStrict()
{
return _strict;
}
/* ------------------------------------------------------------ */
/** Set the strict mode of the security handler.
* <p>
* When in strict mode (the default), the full servlet specification
* will be implemented.
* If not in strict mode, some additional flexibility in configuration
* is allowed:<ul>
* <li>All users do not need to have a role defined in the deployment descriptor
* <li>The * role in a constraint applies to ANY role rather than all roles defined in
* the deployment descriptor.
* </ul>
*
* @param strict the strict to set
* @see #setRoles(Set)
* @see #setConstraintMappings(List, Set)
*/
public void setStrict(boolean strict)
{
_strict = strict;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
@ -408,8 +381,16 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
{ {
_constraintMappings.add(mapping); _constraintMappings.add(mapping);
if (mapping.getConstraint()!=null && mapping.getConstraint().getRoles()!=null) if (mapping.getConstraint()!=null && mapping.getConstraint().getRoles()!=null)
{
//allow for lazy role naming: if a role is named in a security constraint, try and
//add it to the list of declared roles (ie as if it was declared with a security-role
for (String role : mapping.getConstraint().getRoles()) for (String role : mapping.getConstraint().getRoles())
{
if ("*".equals(role) || "**".equals(role))
continue;
addRole(role); addRole(role);
}
}
if (isStarted()) if (isStarted())
{ {
@ -424,8 +405,9 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
@Override @Override
public void addRole(String role) public void addRole(String role)
{ {
//add to list of declared roles
boolean modified = _roles.add(role); boolean modified = _roles.add(role);
if (isStarted() && modified && isStrict()) if (isStarted() && modified)
{ {
// Add the new role to currently defined any role role infos // Add the new role to currently defined any role role infos
for (Map<String,RoleInfo> map : _constraintMap.values()) for (Map<String,RoleInfo> map : _constraintMap.values())
@ -593,26 +575,29 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
//add in the roles //add in the roles
boolean checked = mapping.getConstraint().getAuthenticate(); boolean checked = mapping.getConstraint().getAuthenticate();
ri.setChecked(checked); ri.setChecked(checked);
if (ri.isChecked()) if (ri.isChecked())
{ {
if (mapping.getConstraint().isAnyRole()) if (mapping.getConstraint().isAnyRole())
{ {
if (_strict) // * means matches any defined role
{ for (String role : _roles)
// * means "all defined roles" ri.addRole(role);
for (String role : _roles) ri.setAnyRole(true);
ri.addRole(role); }
} else if (mapping.getConstraint().isAnyAuth())
else {
// * means any role //being authenticated is sufficient, not necessary to check roles
ri.setAnyRole(true); ri.setAnyAuth(true);
} }
else else
{ {
//user must be in one of the named roles
String[] newRoles = mapping.getConstraint().getRoles(); String[] newRoles = mapping.getConstraint().getRoles();
for (String role : newRoles) for (String role : newRoles)
{ {
if (_strict &&!_roles.contains(role)) //check role has been defined
if (!_roles.contains(role))
throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles); throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles);
ri.addRole(role); ri.addRole(role);
} }
@ -753,14 +738,35 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
return true; return true;
} }
if (roleInfo.isAnyRole() && request.getAuthType()!=null) //handle ** role constraint
if (roleInfo.isAnyAuth() && request.getUserPrincipal() != null)
{
return true; return true;
}
//check if user is any of the allowed roles
boolean isUserInRole = false;
for (String role : roleInfo.getRoles()) for (String role : roleInfo.getRoles())
{ {
if (userIdentity.isUserInRole(role, null)) if (userIdentity.isUserInRole(role, null))
return true; {
isUserInRole = true;
break;
}
} }
//handle * role constraint
if (roleInfo.isAnyRole() && request.getUserPrincipal() != null && isUserInRole)
{
return true;
}
//normal role check
if (isUserInRole)
{
return true;
}
return false; return false;
} }

View File

@ -22,6 +22,7 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
/** /**
* RoleInfo
* *
* Badly named class that holds the role and user data constraint info for a * Badly named class that holds the role and user data constraint info for a
* path/http method combination, extracted and combined from security * path/http method combination, extracted and combined from security
@ -31,11 +32,15 @@ import java.util.concurrent.CopyOnWriteArraySet;
*/ */
public class RoleInfo public class RoleInfo
{ {
private boolean _isAnyAuth;
private boolean _isAnyRole; private boolean _isAnyRole;
private boolean _checked; private boolean _checked;
private boolean _forbidden; private boolean _forbidden;
private UserDataConstraint _userDataConstraint; private UserDataConstraint _userDataConstraint;
/**
* List of permitted roles
*/
private final Set<String> _roles = new CopyOnWriteArraySet<String>(); private final Set<String> _roles = new CopyOnWriteArraySet<String>();
public RoleInfo() public RoleInfo()
@ -55,6 +60,7 @@ public class RoleInfo
_forbidden=false; _forbidden=false;
_roles.clear(); _roles.clear();
_isAnyRole=false; _isAnyRole=false;
_isAnyAuth=false;
} }
} }
@ -71,6 +77,7 @@ public class RoleInfo
_checked = true; _checked = true;
_userDataConstraint = null; _userDataConstraint = null;
_isAnyRole=false; _isAnyRole=false;
_isAnyAuth=false;
_roles.clear(); _roles.clear();
} }
} }
@ -84,10 +91,19 @@ public class RoleInfo
{ {
this._isAnyRole=anyRole; this._isAnyRole=anyRole;
if (anyRole) if (anyRole)
{
_checked = true; _checked = true;
_roles.clear(); }
}
public boolean isAnyAuth ()
{
return _isAnyAuth;
}
public void setAnyAuth(boolean anyAuth)
{
this._isAnyAuth=anyAuth;
if (anyAuth)
_checked = true;
} }
public UserDataConstraint getUserDataConstraint() public UserDataConstraint getUserDataConstraint()
@ -126,6 +142,8 @@ public class RoleInfo
setChecked(true); setChecked(true);
else if (other._isAnyRole) else if (other._isAnyRole)
setAnyRole(true); setAnyRole(true);
else if (other._isAnyAuth)
setAnyAuth(true);
else if (!_isAnyRole) else if (!_isAnyRole)
{ {
for (String r : other._roles) for (String r : other._roles)

View File

@ -18,39 +18,20 @@
package org.eclipse.jetty.security; package org.eclipse.jetty.security;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.UserIdentity.Scope;
/** /**
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
*/ */
public class UserAuthentication implements Authentication.User public class UserAuthentication extends AbstractUserAuthentication
{ {
private final String _method;
private final UserIdentity _userIdentity;
public UserAuthentication(String method, UserIdentity userIdentity) public UserAuthentication(String method, UserIdentity userIdentity)
{ {
_method = method; super(method, userIdentity);
_userIdentity = userIdentity;
}
public String getAuthMethod()
{
return _method;
} }
public UserIdentity getUserIdentity()
{
return _userIdentity;
}
public boolean isUserInRole(Scope scope, String role)
{
return _userIdentity.isUserInRole(role, scope);
}
@Override @Override
public String toString() public String toString()

View File

@ -29,16 +29,15 @@ import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionEvent;
import org.eclipse.jetty.security.AbstractUserAuthentication;
import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.server.Authentication;
import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.UserIdentity.Scope;
import org.eclipse.jetty.server.session.AbstractSession; import org.eclipse.jetty.server.session.AbstractSession;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
public class SessionAuthentication implements Authentication.User, Serializable, HttpSessionActivationListener, HttpSessionBindingListener public class SessionAuthentication extends AbstractUserAuthentication implements Serializable, HttpSessionActivationListener, HttpSessionBindingListener
{ {
private static final Logger LOG = Log.getLogger(SessionAuthentication.class); private static final Logger LOG = Log.getLogger(SessionAuthentication.class);
@ -48,35 +47,17 @@ public class SessionAuthentication implements Authentication.User, Serializable,
public final static String __J_AUTHENTICATED="org.eclipse.jetty.security.UserIdentity"; public final static String __J_AUTHENTICATED="org.eclipse.jetty.security.UserIdentity";
private final String _method;
private final String _name; private final String _name;
private final Object _credentials; private final Object _credentials;
private transient UserIdentity _userIdentity;
private transient HttpSession _session; private transient HttpSession _session;
public SessionAuthentication(String method, UserIdentity userIdentity, Object credentials) public SessionAuthentication(String method, UserIdentity userIdentity, Object credentials)
{ {
_method = method; super(method, userIdentity);
_userIdentity = userIdentity; _name=userIdentity.getUserPrincipal().getName();
_name=_userIdentity.getUserPrincipal().getName();
_credentials=credentials; _credentials=credentials;
} }
public String getAuthMethod()
{
return _method;
}
public UserIdentity getUserIdentity()
{
return _userIdentity;
}
public boolean isUserInRole(Scope scope, String role)
{
return _userIdentity.isUserInRole(role, scope);
}
private void readObject(ObjectInputStream stream) private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException

View File

@ -81,7 +81,8 @@ public class ConstraintTest
SessionHandler _session = new SessionHandler(); SessionHandler _session = new SessionHandler();
HashLoginService _loginService = new HashLoginService(TEST_REALM); HashLoginService _loginService = new HashLoginService(TEST_REALM);
_loginService.putUser("user",new Password("password")); _loginService.putUser("user0", new Password("password"), new String[]{});
_loginService.putUser("user",new Password("password"), new String[] {"user"});
_loginService.putUser("user2",new Password("password"), new String[] {"user"}); _loginService.putUser("user2",new Password("password"), new String[] {"user"});
_loginService.putUser("admin",new Password("password"), new String[] {"user","administrator"}); _loginService.putUser("admin",new Password("password"), new String[] {"user","administrator"});
_loginService.putUser("user3", new Password("password"), new String[] {"foo"}); _loginService.putUser("user3", new Password("password"), new String[] {"foo"});
@ -173,7 +174,16 @@ public class ConstraintTest
mapping6.setPathSpec("/data/*"); mapping6.setPathSpec("/data/*");
mapping6.setConstraint(constraint6); mapping6.setConstraint(constraint6);
return Arrays.asList(mapping0, mapping1, mapping2, mapping3, mapping4, mapping5, mapping6); Constraint constraint7 = new Constraint();
constraint7.setAuthenticate(true);
constraint7.setName("** constraint");
constraint7.setRoles(new String[]{Constraint.ANY_AUTH,"user"}); //the "user" role is superfluous once ** has been defined
ConstraintMapping mapping7 = new ConstraintMapping();
mapping7.setPathSpec("/starstar/*");
mapping7.setConstraint(constraint7);
return Arrays.asList(mapping0, mapping1, mapping2, mapping3, mapping4, mapping5, mapping6, mapping7);
} }
@Test @Test
@ -246,7 +256,6 @@ public class ConstraintTest
_security.setAuthenticator(new BasicAuthenticator()); _security.setAuthenticator(new BasicAuthenticator());
_security.setStrict(false);
_server.start(); _server.start();
String response; String response;
@ -331,7 +340,6 @@ public class ConstraintTest
public void testFormDispatch() throws Exception public void testFormDispatch() throws Exception
{ {
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",true)); _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",true));
_security.setStrict(false);
_server.start(); _server.start();
String response; String response;
@ -386,7 +394,6 @@ public class ConstraintTest
public void testFormRedirect() throws Exception public void testFormRedirect() throws Exception
{ {
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false)); _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false));
_security.setStrict(false);
_server.start(); _server.start();
String response; String response;
@ -443,7 +450,6 @@ public class ConstraintTest
public void testFormPostRedirect() throws Exception public void testFormPostRedirect() throws Exception
{ {
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false)); _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false));
_security.setStrict(false);
_server.start(); _server.start();
String response; String response;
@ -513,7 +519,6 @@ public class ConstraintTest
public void testFormNoCookies() throws Exception public void testFormNoCookies() throws Exception
{ {
_security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false)); _security.setAuthenticator(new FormAuthenticator("/testLoginPage","/testErrorPage",false));
_security.setStrict(false);
_server.start(); _server.start();
String response; String response;
@ -586,7 +591,7 @@ public class ConstraintTest
assertThat(response,containsString("WWW-Authenticate: basic realm=\"TestRealm\"")); assertThat(response,containsString("WWW-Authenticate: basic realm=\"TestRealm\""));
response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" + response = _connector.getResponses("GET /ctx/auth/info HTTP/1.0\r\n" +
"Authorization: Basic " + B64Code.encode("user:password") + "\r\n" + "Authorization: Basic " + B64Code.encode("user3:password") + "\r\n" +
"\r\n"); "\r\n");
assertThat(response,startsWith("HTTP/1.1 403")); assertThat(response,startsWith("HTTP/1.1 403"));
@ -660,9 +665,9 @@ public class ConstraintTest
response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" +
"Cookie: JSESSIONID=" + session + "\r\n" + "Cookie: JSESSIONID=" + session + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" +
"Content-Length: 35\r\n" + "Content-Length: 36\r\n" +
"\r\n" + "\r\n" +
"j_username=user&j_password=password\r\n"); "j_username=user0&j_password=password\r\n");
assertThat(response,startsWith("HTTP/1.1 302 ")); assertThat(response,startsWith("HTTP/1.1 302 "));
assertThat(response,containsString("Location")); assertThat(response,containsString("Location"));
assertThat(response,containsString("/ctx/auth/info")); assertThat(response,containsString("/ctx/auth/info"));
@ -771,9 +776,9 @@ public class ConstraintTest
response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" + response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" +
"Cookie: JSESSIONID=" + session + "\r\n" + "Cookie: JSESSIONID=" + session + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" +
"Content-Length: 35\r\n" + "Content-Length: 36\r\n" +
"\r\n" + "\r\n" +
"j_username=user&j_password=password\r\n"); "j_username=user3&j_password=password\r\n");
assertThat(response,startsWith("HTTP/1.1 302 ")); assertThat(response,startsWith("HTTP/1.1 302 "));
assertThat(response,containsString("Location")); assertThat(response,containsString("Location"));
assertThat(response,containsString("/ctx/auth/info")); assertThat(response,containsString("/ctx/auth/info"));
@ -816,12 +821,35 @@ public class ConstraintTest
"\r\n"); "\r\n");
assertThat(response,startsWith("HTTP/1.1 200 OK")); assertThat(response,startsWith("HTTP/1.1 200 OK"));
//check user2 does not have right role to access /admin/*
response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" + response = _connector.getResponses("GET /ctx/admin/info HTTP/1.0\r\n" +
"Cookie: JSESSIONID=" + session + "\r\n" + "Cookie: JSESSIONID=" + session + "\r\n" +
"\r\n"); "\r\n");
assertThat(response,startsWith("HTTP/1.1 403")); assertThat(response,startsWith("HTTP/1.1 403"));
assertThat(response,containsString("!role")); assertThat(response,containsString("!role"));
//log in as user3, who doesn't have a valid role, but we are checking a constraint
//of ** which just means they have to be authenticated
response = _connector.getResponses("GET /ctx/starstar/info HTTP/1.0\r\n\r\n");
assertThat(response,startsWith("HTTP/1.1 302 "));
assertThat(response,containsString("testLoginPage"));
session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx"));
response = _connector.getResponses("POST /ctx/j_security_check HTTP/1.0\r\n" +
"Cookie: JSESSIONID=" + session + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"Content-Length: 36\r\n" +
"\r\n" +
"j_username=user3&j_password=password\r\n");
assertThat(response,startsWith("HTTP/1.1 302 "));
assertThat(response,containsString("Location"));
assertThat(response,containsString("/ctx/starstar/info"));
session = response.substring(response.indexOf("JSESSIONID=") + 11, response.indexOf(";Path=/ctx"));
response = _connector.getResponses("GET /ctx/starstar/info HTTP/1.0\r\n" +
"Cookie: JSESSIONID=" + session + "\r\n" +
"\r\n");
assertThat(response,startsWith("HTTP/1.1 200 OK"));
// log in again as admin // log in again as admin
@ -900,7 +928,7 @@ public class ConstraintTest
RoleCheckHandler check=new RoleCheckHandler(); RoleCheckHandler check=new RoleCheckHandler();
_security.setHandler(check); _security.setHandler(check);
_security.setAuthenticator(new BasicAuthenticator()); _security.setAuthenticator(new BasicAuthenticator());
_security.setStrict(false); //_security.setStrict(false);
_server.start(); _server.start();
@ -932,7 +960,7 @@ public class ConstraintTest
public void testDeferredBasic() throws Exception public void testDeferredBasic() throws Exception
{ {
_security.setAuthenticator(new BasicAuthenticator()); _security.setAuthenticator(new BasicAuthenticator());
_security.setStrict(false); //_security.setStrict(false);
_server.start(); _server.start();
String response; String response;
@ -959,7 +987,7 @@ public class ConstraintTest
public void testRelaxedMethod() throws Exception public void testRelaxedMethod() throws Exception
{ {
_security.setAuthenticator(new BasicAuthenticator()); _security.setAuthenticator(new BasicAuthenticator());
_security.setStrict(false); //_security.setStrict(false);
_server.start(); _server.start();
String response; String response;

View File

@ -239,7 +239,6 @@ public class SpecExampleConstraintTest
{ {
_security.setAuthenticator(new BasicAuthenticator()); _security.setAuthenticator(new BasicAuthenticator());
_security.setStrict(false);
_server.start(); _server.start();
String response; String response;

View File

@ -23,6 +23,8 @@ import java.util.Arrays;
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Constraint
*
* Describe an auth and/or data constraint. * Describe an auth and/or data constraint.
* *
* *
@ -65,6 +67,8 @@ public class Constraint implements Cloneable, Serializable
public final static String NONE = "NONE"; public final static String NONE = "NONE";
public final static String ANY_ROLE = "*"; public final static String ANY_ROLE = "*";
public final static String ANY_AUTH = "**"; //Servlet Spec 3.1 pg 140
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
private String _name; private String _name;
@ -74,6 +78,8 @@ public class Constraint implements Cloneable, Serializable
private int _dataConstraint = DC_UNSET; private int _dataConstraint = DC_UNSET;
private boolean _anyRole = false; private boolean _anyRole = false;
private boolean _anyAuth = false;
private boolean _authenticate = false; private boolean _authenticate = false;
@ -119,9 +125,15 @@ public class Constraint implements Cloneable, Serializable
{ {
_roles = roles; _roles = roles;
_anyRole = false; _anyRole = false;
_anyAuth = false;
if (roles != null) if (roles != null)
for (int i = roles.length; !_anyRole && i-- > 0;) {
for (int i = roles.length; i-- > 0;)
{
_anyRole |= ANY_ROLE.equals(roles[i]); _anyRole |= ANY_ROLE.equals(roles[i]);
_anyAuth |= ANY_AUTH.equals(roles[i]);
}
}
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -132,6 +144,16 @@ public class Constraint implements Cloneable, Serializable
{ {
return _anyRole; return _anyRole;
} }
/* ------------------------------------------------------------ */
/** Servlet Spec 3.1, pg 140
* @return True if any authenticated user is permitted (ie a role "**" was specified in the constraint).
*/
public boolean isAnyAuth()
{
return _anyAuth;
}
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**

View File

@ -155,7 +155,6 @@ public class JdbcLoginServiceTest
security.setConstraintMappings(Collections.singletonList(mapping), knownRoles); security.setConstraintMappings(Collections.singletonList(mapping), knownRoles);
security.setAuthenticator(new BasicAuthenticator()); security.setAuthenticator(new BasicAuthenticator());
security.setLoginService(loginService); security.setLoginService(loginService);
security.setStrict(false);
ServletContextHandler root = new ServletContextHandler(); ServletContextHandler root = new ServletContextHandler();
root.setContextPath("/"); root.setContextPath("/");

View File

@ -15,7 +15,7 @@ This page contains several links to test the authentication constraints:
<li><a href="auth2">auth2/index.html</a> - Authenticated (tests FormAuthenticator.setAlwaysSaveUri()) </li> <li><a href="auth2">auth2/index.html</a> - Authenticated (tests FormAuthenticator.setAlwaysSaveUri()) </li>
<li><a href="dump/auth/noaccess/info">dump/auth/noaccess/*</a> - Forbidden</li> <li><a href="dump/auth/noaccess/info">dump/auth/noaccess/*</a> - Forbidden</li>
<li><a href="dump/auth/relax/info">dump/auth/relax/*</a> - Allowed</li> <li><a href="dump/auth/relax/info">dump/auth/relax/*</a> - Allowed</li>
<li><a href="dump/auth/info">dump/auth/*</a> - Authenticated any user</li> <li><a href="dump/auth/info">dump/auth/*</a> - Authenticated any user with any role</li>
<li><a href="dump/auth/admin/info">dump/auth/admin/*</a> - Authenticated admin role (<a href="session/?Action=Invalidate">click</a> to invalidate session)</li> <li><a href="dump/auth/admin/info">dump/auth/admin/*</a> - Authenticated admin role (<a href="session/?Action=Invalidate">click</a> to invalidate session)</li>
<li><a href="dump/auth/ssl/info">dump/auth/ssl/*</a> - Confidential</li> <li><a href="dump/auth/ssl/info">dump/auth/ssl/*</a> - Confidential</li>
<li><a href="rego/info">rego/info/*</a> - Authenticated admin role from programmatic security (<a href="session/?Action=Invalidate">click</a> to invalidate session)</li> <li><a href="rego/info">rego/info/*</a> - Authenticated admin role from programmatic security (<a href="session/?Action=Invalidate">click</a> to invalidate session)</li>