405533 Implement special role ** for security constraints
This commit is contained in:
parent
a7073d05a6
commit
87d4690462
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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("/");
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue