diff options
Diffstat (limited to 'jetty-security/src/main/java')
22 files changed, 493 insertions, 488 deletions
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 41774c5c93..c9ed72a86e 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -19,7 +19,6 @@ package org.eclipse.jetty.security; import java.util.Set; - import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -32,10 +31,10 @@ import org.eclipse.jetty.server.Server; * Authenticator Interface * <p> * An Authenticator is responsible for checking requests and sending - * response challenges in order to authenticate a request. + * response challenges in order to authenticate a request. * Various types of {@link Authentication} are returned in order to * signal the next step in authentication. - * + * * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ */ public interface Authenticator @@ -46,27 +45,27 @@ public interface Authenticator * @param configuration */ void setConfiguration(AuthConfiguration configuration); - + /* ------------------------------------------------------------ */ /** * @return The name of the authentication method */ String getAuthMethod(); - + /* ------------------------------------------------------------ */ /** Validate a response * @param request The request * @param response The response * @param mandatory True if authentication is mandatory. - * @return An Authentication. If Authentication is successful, this will be a {@link org.eclipse.jetty.server.Authentication.User}. If a response has + * @return An Authentication. If Authentication is successful, this will be a {@link org.eclipse.jetty.server.Authentication.User}. If a response has * been sent by the Authenticator (which can be done for both successful and unsuccessful authentications), then the result will - * implement {@link org.eclipse.jetty.server.Authentication.ResponseSent}. If Authentication is not manditory, then a + * implement {@link org.eclipse.jetty.server.Authentication.ResponseSent}. If Authentication is not manditory, then a * {@link org.eclipse.jetty.server.Authentication.Deferred} may be returned. - * + * * @throws ServerAuthException */ Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException; - + /* ------------------------------------------------------------ */ /** * @param request @@ -77,33 +76,33 @@ public interface Authenticator * @throws ServerAuthException */ boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, User validatedUser) throws ServerAuthException; - - + + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ - /** + /** * Authenticator Configuration */ interface AuthConfiguration { String getAuthMethod(); String getRealmName(); - + /** Get a SecurityHandler init parameter * @see SecurityHandler#getInitParameter(String) * @param param parameter name * @return Parameter value or null */ String getInitParameter(String param); - + /* ------------------------------------------------------------ */ /** Get a SecurityHandler init parameter names * @see SecurityHandler#getInitParameterNames() * @return Set of parameter names */ Set<String> getInitParameterNames(); - + LoginService getLoginService(); IdentityService getIdentityService(); boolean isSessionRenewedOnAuthentication(); @@ -112,7 +111,7 @@ public interface Authenticator /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ - /** + /** * Authenticator Factory */ interface Factory diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java index 5712c1df92..eb9235ab42 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java @@ -37,33 +37,32 @@ import javax.servlet.ServletSecurityElement; import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic; import javax.servlet.annotation.ServletSecurity.TransportGuarantee; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.PathMap; -import org.eclipse.jetty.server.AbstractHttpConnection; -import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.HttpChannelConfig; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.StringMap; -import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.security.Constraint; /* ------------------------------------------------------------ */ /** * Handler to enforce SecurityConstraints. This implementation is servlet spec - * 3.0 compliant and precomputes the constraint combinations for runtime + * 3.0 compliant and pre-computes the constraint combinations for runtime * efficiency. * */ public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware { private static final String OMISSION_SUFFIX = ".omission"; - - private final List<ConstraintMapping> _constraintMappings= new CopyOnWriteArrayList<ConstraintMapping>(); - private final Set<String> _roles = new CopyOnWriteArraySet<String>(); - private final PathMap _constraintMap = new PathMap(); + private static final String ALL_METHODS = "*"; + private final List<ConstraintMapping> _constraintMappings= new CopyOnWriteArrayList<>(); + private final Set<String> _roles = new CopyOnWriteArraySet<>(); + private final PathMap<Map<String, RoleInfo>> _constraintMap = new PathMap<>(); private boolean _strict = true; - - + /* ------------------------------------------------------------ */ /** * @return @@ -264,11 +263,12 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint if (methodOmissions.size() > 0) defaultMapping.setMethodOmissions(methodOmissions.toArray(new String[methodOmissions.size()])); - + return mappings; } + /* ------------------------------------------------------------ */ /** Get the strict mode. * @return true if the security handler is running in strict mode. @@ -303,12 +303,14 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /** * @return Returns the constraintMappings. */ + @Override public List<ConstraintMapping> getConstraintMappings() { return _constraintMappings; } /* ------------------------------------------------------------ */ + @Override public Set<String> getRoles() { return _roles; @@ -350,6 +352,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr * The constraintMappings to set. * @param roles The known roles (or null to determine them from the mappings) */ + @Override public void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles) { _constraintMappings.clear(); @@ -357,14 +360,14 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr if (roles==null) { - roles = new HashSet<String>(); + roles = new HashSet<>(); for (ConstraintMapping cm : constraintMappings) { String[] cmr = cm.getConstraint().getRoles(); if (cmr!=null) { for (String r : cmr) - if (!"*".equals(r)) + if (!ALL_METHODS.equals(r)) roles.add(r); } } @@ -400,6 +403,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /** * @see org.eclipse.jetty.security.ConstraintAware#addConstraintMapping(org.eclipse.jetty.security.ConstraintMapping) */ + @Override public void addConstraintMapping(ConstraintMapping mapping) { _constraintMappings.add(mapping); @@ -417,13 +421,14 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /** * @see org.eclipse.jetty.security.ConstraintAware#addRole(java.lang.String) */ + @Override public void addRole(String role) { boolean modified = _roles.add(role); - if (isStarted() && modified && _strict) + if (isStarted() && modified && isStrict()) { // Add the new role to currently defined any role role infos - for (Map<String,RoleInfo> map : (Collection<Map<String,RoleInfo>>)_constraintMap.values()) + for (Map<String,RoleInfo> map : _constraintMap.values()) { for (RoleInfo info : map.values()) { @@ -457,10 +462,8 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr @Override protected void doStop() throws Exception { - _constraintMap.clear(); - _constraintMappings.clear(); - _roles.clear(); super.doStop(); + _constraintMap.clear(); } @@ -473,24 +476,25 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr */ protected void processConstraintMapping(ConstraintMapping mapping) { - Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.get(mapping.getPathSpec()); + Map<String, RoleInfo> mappings = _constraintMap.get(mapping.getPathSpec()); if (mappings == null) { - mappings = new StringMap(); + mappings = new StringMap<>(); _constraintMap.put(mapping.getPathSpec(),mappings); } - RoleInfo allMethodsRoleInfo = mappings.get(null); + RoleInfo allMethodsRoleInfo = mappings.get(ALL_METHODS); if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden()) return; - + if (mapping.getMethodOmissions() != null && mapping.getMethodOmissions().length > 0) { - processConstraintMappingWithMethodOmissions(mapping, mappings); return; } - String httpMethod = mapping.getMethod(); + String httpMethod = mapping.getMethod(); + if (httpMethod==null) + httpMethod=ALL_METHODS; RoleInfo roleInfo = mappings.get(httpMethod); if (roleInfo == null) { @@ -509,10 +513,10 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr if (roleInfo.isForbidden()) { - if (httpMethod == null) + if (httpMethod.equals(ALL_METHODS)) { mappings.clear(); - mappings.put(null,roleInfo); + mappings.put(ALL_METHODS,roleInfo); } } else @@ -592,32 +596,32 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr if (ri.isChecked()) { if (mapping.getConstraint().isAnyRole()) - { - if (_strict) - { - // * means "all defined roles" - for (String role : _roles) + { + if (_strict) + { + // * means "all defined roles" + for (String role : _roles) ri.addRole(role); - } - else - // * means any role + } + else + // * means any role ri.setAnyRole(true); - } - else - { + } + else + { String[] newRoles = mapping.getConstraint().getRoles(); - for (String role : newRoles) - { - if (_strict &&!_roles.contains(role)) - throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles); + for (String role : newRoles) + { + if (_strict &&!_roles.contains(role)) + throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles); ri.addRole(role); - } - } - } - } - } + } + } + } + } + } + - /* ------------------------------------------------------------ */ /** * Find constraints that apply to the given path. @@ -631,7 +635,8 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr * * @see org.eclipse.jetty.security.SecurityHandler#prepareConstraintInfo(java.lang.String, org.eclipse.jetty.server.Request) */ - protected Object prepareConstraintInfo(String pathInContext, Request request) + @Override + protected RoleInfo prepareConstraintInfo(String pathInContext, Request request) { Map<String, RoleInfo> mappings = (Map<String, RoleInfo>)_constraintMap.match(pathInContext); @@ -645,7 +650,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr List<RoleInfo> applicableConstraints = new ArrayList<RoleInfo>(); //Get info for constraint that matches all methods if it exists - RoleInfo all = mappings.get(null); + RoleInfo all = mappings.get(ALL_METHODS); if (all != null) applicableConstraints.add(all); @@ -672,58 +677,33 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr } return roleInfo; } + return null; } - - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.security.SecurityHandler#checkUserDataPermissions(java.lang.String, org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object) - */ - protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Object constraintInfo) throws IOException + + @Override + protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response, RoleInfo roleInfo) throws IOException { - if (constraintInfo == null) + if (roleInfo == null) return true; - RoleInfo roleInfo = (RoleInfo)constraintInfo; if (roleInfo.isForbidden()) return false; - UserDataConstraint dataConstraint = roleInfo.getUserDataConstraint(); if (dataConstraint == null || dataConstraint == UserDataConstraint.None) - { return true; - } - AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection(); - Connector connector = connection.getConnector(); - if (dataConstraint == UserDataConstraint.Integral) - { - if (connector.isIntegral(request)) - return true; - if (connector.getIntegralPort() > 0) - { - String url = connector.getIntegralScheme() + "://" + request.getServerName() + ":" + connector.getIntegralPort() + request.getRequestURI(); - if (request.getQueryString() != null) - url += "?" + request.getQueryString(); - response.setContentLength(0); - response.sendRedirect(url); - } - else - response.sendError(Response.SC_FORBIDDEN,"!Integral"); + HttpChannelConfig httpConfig = HttpChannel.getCurrentHttpChannel().getHttpChannelConfig(); - request.setHandled(true); - return false; - } - else if (dataConstraint == UserDataConstraint.Confidential) + if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral) { - if (connector.isConfidential(request)) + if (request.isSecure()) return true; - if (connector.getConfidentialPort() > 0) + if (httpConfig.getSecurePort() > 0) { - String url = connector.getConfidentialScheme() + "://" + request.getServerName() + ":" + connector.getConfidentialPort() + String url = httpConfig.getSecureScheme() + "://" + request.getServerName() + ":" + httpConfig.getSecurePort() + request.getRequestURI(); if (request.getQueryString() != null) url += "?" + request.getQueryString(); @@ -732,7 +712,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr response.sendRedirect(url); } else - response.sendError(Response.SC_FORBIDDEN,"!Confidential"); + response.sendError(HttpStatus.FORBIDDEN_403,"!Secure"); request.setHandled(true); return false; @@ -743,18 +723,11 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr } } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.security.SecurityHandler#isAuthMandatory(org.eclipse.jetty.server.Request, org.eclipse.jetty.server.Response, java.lang.Object) - */ + + @Override protected boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo) { - if (constraintInfo == null) - { - return false; - } - return ((RoleInfo)constraintInfo).isChecked(); + return constraintInfo != null && ((RoleInfo)constraintInfo).isChecked(); } @@ -792,15 +765,13 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr @Override public void dump(Appendable out,String indent) throws IOException { - dumpThis(out); - dump(out,indent, + // TODO these should all be beans + dumpBeans(out,indent, Collections.singleton(getLoginService()), Collections.singleton(getIdentityService()), Collections.singleton(getAuthenticator()), Collections.singleton(_roles), - _constraintMap.entrySet(), - getBeans(), - TypeUtil.asList(getHandlers())); + _constraintMap.entrySet()); } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java index e8a70785c6..06e0f205c9 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java @@ -19,7 +19,6 @@ package org.eclipse.jetty.security; import java.security.Principal; - import javax.security.auth.Subject; import org.eclipse.jetty.server.UserIdentity; @@ -31,7 +30,7 @@ import org.eclipse.jetty.server.UserIdentity; * This service handles only role reference maps passed in an * associated {@link org.eclipse.jetty.server.UserIdentity.Scope}. If there are roles * refs present, then associate will wrap the UserIdentity with one - * that uses the role references in the + * that uses the role references in the * {@link org.eclipse.jetty.server.UserIdentity#isUserInRole(String, org.eclipse.jetty.server.UserIdentity.Scope)} * implementation. All other operations are effectively noops. * @@ -42,10 +41,10 @@ public class DefaultIdentityService implements IdentityService public DefaultIdentityService() { } - + /* ------------------------------------------------------------ */ - /** - * If there are roles refs present in the scope, then wrap the UserIdentity + /** + * If there are roles refs present in the scope, then wrap the UserIdentity * with one that uses the role references in the {@link UserIdentity#isUserInRole(String, org.eclipse.jetty.server.UserIdentity.Scope)} */ public Object associate(UserIdentity user) @@ -54,7 +53,7 @@ public class DefaultIdentityService implements IdentityService } /* ------------------------------------------------------------ */ - public void disassociate(Object previous) + public void disassociate(Object previous) { } @@ -86,5 +85,5 @@ public class DefaultIdentityService implements IdentityService { return new DefaultUserIdentity(subject,userPrincipal,roles); } - + } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java index 3d7e8cee0b..ca196134ca 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java @@ -19,7 +19,6 @@ package org.eclipse.jetty.security; import java.security.Principal; - import javax.security.auth.Subject; import org.eclipse.jetty.server.UserIdentity; @@ -31,11 +30,11 @@ import org.eclipse.jetty.server.UserIdentity; * */ public class DefaultUserIdentity implements UserIdentity -{ +{ private final Subject _subject; private final Principal _userPrincipal; private final String[] _roles; - + public DefaultUserIdentity(Subject subject, Principal userPrincipal, String[] roles) { _subject=subject; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java index d754c71d0a..38444236a5 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java @@ -22,7 +22,6 @@ import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import java.util.Random; - import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index 8cdc3dd1e2..ac7d67b9d2 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -19,7 +19,6 @@ package org.eclipse.jetty.security; import java.security.Principal; - import javax.security.auth.Subject; import org.eclipse.jetty.server.Request; @@ -28,26 +27,26 @@ import org.eclipse.jetty.server.UserIdentity; /* ------------------------------------------------------------ */ /** * Associates UserIdentities from with threads and UserIdentity.Contexts. - * + * */ public interface IdentityService { - final static String[] NO_ROLES = new String[]{}; - + final static String[] NO_ROLES = new String[]{}; + /* ------------------------------------------------------------ */ /** * Associate a user identity with the current thread. - * This is called with as a thread enters the + * This is called with as a thread enters the * {@link SecurityHandler#handle(String, Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} * method and then again with a null argument as that call exits. * @param user The current user or null for no user to associated. * @return an object representing the previous associated state */ Object associate(UserIdentity user); - + /* ------------------------------------------------------------ */ - /** - * Disassociate the user identity from the current thread + /** + * Disassociate the user identity from the current thread * and restore previous identity. * @param previous The opaque object returned from a call to {@link IdentityService#associate(UserIdentity)} */ @@ -61,7 +60,7 @@ public interface IdentityService * @return The previous runAsToken or null. */ Object setRunAs(UserIdentity user, RunAsToken token); - + /* ------------------------------------------------------------ */ /** * Disassociate the current runAsToken from the thread @@ -74,7 +73,7 @@ public interface IdentityService /** * Create a new UserIdentity for use with this identity service. * The UserIdentity should be immutable and able to be cached. - * + * * @param subject Subject to include in UserIdentity * @param userPrincipal Principal to include in UserIdentity. This will be returned from getUserPrincipal calls * @param roles set of roles to include in UserIdentity. diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java index 827b315be3..9d7079ff3c 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java @@ -25,7 +25,6 @@ import java.security.Principal; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; - import javax.security.auth.Subject; import org.eclipse.jetty.server.UserIdentity; @@ -40,7 +39,7 @@ import org.eclipse.jetty.util.security.Credential; /** * A login service that keeps UserIdentities in a concurrent map * either as the source or a cache of the users. - * + * */ public abstract class MappedLoginService extends AbstractLifeCycle implements LoginService { @@ -54,7 +53,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo protected MappedLoginService() { } - + /* ------------------------------------------------------------ */ /** Get the name. * @return the name @@ -63,7 +62,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo { return _name; } - + /* ------------------------------------------------------------ */ /** Get the identityService. * @return the identityService @@ -72,7 +71,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo { return _identityService; } - + /* ------------------------------------------------------------ */ /** Get the users. * @return the users @@ -81,7 +80,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo { return _users; } - + /* ------------------------------------------------------------ */ /** Set the identityService. * @param identityService the identityService to set @@ -136,17 +135,17 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo /* ------------------------------------------------------------ */ public void logout(UserIdentity identity) - { + { LOG.debug("logout {}",identity); } - + /* ------------------------------------------------------------ */ @Override public String toString() { return this.getClass().getSimpleName()+"["+_name+"]"; } - + /* ------------------------------------------------------------ */ /** Put user into realm. * Called by implementations to put the user data loaded from @@ -163,7 +162,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo else { Credential credential = (info instanceof Credential)?(Credential)info:Credential.getCredential(info.toString()); - + Principal userPrincipal = new KnownUser(userName,credential); Subject subject = new Subject(); subject.getPrincipals().add(userPrincipal); @@ -171,11 +170,11 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo subject.setReadOnly(); identity=_identityService.newUserIdentity(subject,userPrincipal,IdentityService.NO_ROLES); } - + _users.put(userName,identity); return identity; } - + /* ------------------------------------------------------------ */ /** Put user into realm. * @param userName The user to add @@ -189,7 +188,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo Subject subject = new Subject(); subject.getPrincipals().add(userPrincipal); subject.getPrivateCredentials().add(credential); - + if (roles!=null) for (String role : roles) subject.getPrincipals().add(new RolePrincipal(role)); @@ -198,13 +197,13 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo UserIdentity identity=_identityService.newUserIdentity(subject,userPrincipal,roles); _users.put(userName,identity); return identity; - } - + } + /* ------------------------------------------------------------ */ public void removeUser(String username) { _users.remove(username); - } + } /* ------------------------------------------------------------ */ /** @@ -213,10 +212,10 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo public UserIdentity login(String username, Object credentials) { UserIdentity user = _users.get(username); - + if (user==null) user = loadUser(username); - + if (user!=null) { UserPrincipal principal = (UserPrincipal)user.getUserPrincipal(); @@ -231,16 +230,16 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo { if (_users.containsKey(user.getUserPrincipal().getName())) return true; - + if (loadUser(user.getUserPrincipal().getName())!=null) return true; - + return false; } /* ------------------------------------------------------------ */ protected abstract UserIdentity loadUser(String username); - + /* ------------------------------------------------------------ */ protected abstract void loadUsers() throws IOException; @@ -253,7 +252,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo boolean authenticate(Object credentials); public boolean isAuthenticated(); } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ @@ -287,14 +286,14 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo { return "Anonymous"; } - + public boolean authenticate(Object credentials) { return false; } - + } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ @@ -303,7 +302,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo private static final long serialVersionUID = -6226920753748399662L; private final String _name; private final Credential _credential; - + /* -------------------------------------------------------- */ public KnownUser(String name,Credential credential) { @@ -316,13 +315,13 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo { return _credential!=null && _credential.check(credentials); } - + /* ------------------------------------------------------------ */ public String getName() { return _name; } - + /* -------------------------------------------------------- */ public boolean isAuthenticated() { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java index 2c892f6dea..afff5c1033 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -30,7 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; - import javax.security.auth.Subject; import org.eclipse.jetty.security.MappedLoginService.KnownUser; @@ -46,16 +45,16 @@ import org.eclipse.jetty.util.security.Credential; /** * PropertyUserStore - * + * * This class monitors a property file of the format mentioned below and notifies registered listeners of the changes to the the given file. - * + * * <PRE> * username: password [,rolename ...] * </PRE> - * + * * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password * checksums. - * + * * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:. */ public class PropertyUserStore extends AbstractLifeCycle @@ -84,7 +83,7 @@ public class PropertyUserStore extends AbstractLifeCycle { _config = config; } - + /* ------------------------------------------------------------ */ public UserIdentity getUserIdentity(String userName) { @@ -157,7 +156,7 @@ public class PropertyUserStore extends AbstractLifeCycle } known.add(username); Credential credential = Credential.getCredential(credentials); - + Principal userPrincipal = new KnownUser(username,credential); Subject subject = new Subject(); subject.getPrincipals().add(userPrincipal); @@ -170,9 +169,9 @@ public class PropertyUserStore extends AbstractLifeCycle subject.getPrincipals().add(new RolePrincipal(role)); } } - + subject.setReadOnly(); - + _knownUserIdentities.put(username,_identityService.newUserIdentity(subject,userPrincipal,roleArray)); notifyUpdate(username,credential,roleArray); } @@ -216,8 +215,8 @@ public class PropertyUserStore extends AbstractLifeCycle /** * Depending on the value of the refresh interval, this method will either start up a scanner thread that will monitor the properties file for changes after * it has initially loaded it. Otherwise the users will be loaded and there will be no active monitoring thread so changes will not be detected. - * - * + * + * * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() */ protected void doStart() throws Exception @@ -300,7 +299,7 @@ public class PropertyUserStore extends AbstractLifeCycle /** * Notifies the registered listeners of potential updates to a user - * + * * @param username * @param credential * @param roleArray @@ -318,7 +317,7 @@ public class PropertyUserStore extends AbstractLifeCycle /** * notifies the registered listeners that a user has been removed. - * + * * @param username */ private void notifyRemove(String username) diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 95bcbde894..34a5246f9c 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -20,12 +20,12 @@ package org.eclipse.jetty.security; import java.io.IOException; import java.security.Principal; +import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -33,9 +33,9 @@ import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import org.eclipse.jetty.security.authentication.DeferredAuthentication; -import org.eclipse.jetty.server.AbstractHttpConnection; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.UserIdentity; @@ -55,11 +55,11 @@ import org.eclipse.jetty.util.log.Logger; * or will be create during {@link #start()} with a call to * either the default or set AuthenticatorFactory. * <p> - * SecurityHandler has a set of initparameters that are used by the + * SecurityHandler has a set of initparameters that are used by the * Authentication.Configuration. At startup, any context init parameters - * that start with "org.eclipse.jetty.security." that do not have - * values in the SecurityHandler init parameters, are copied. - * + * that start with "org.eclipse.jetty.security." that do not have + * values in the SecurityHandler init parameters, are copied. + * */ public abstract class SecurityHandler extends HandlerWrapper implements Authenticator.AuthConfiguration { @@ -71,21 +71,22 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti private Authenticator.Factory _authenticatorFactory=new DefaultAuthenticatorFactory(); private String _realmName; private String _authMethod; - private final Map<String,String> _initParameters=new HashMap<String,String>(); + private final Map<String,String> _initParameters=new HashMap<>(); private LoginService _loginService; - private boolean _loginServiceShared; private IdentityService _identityService; private boolean _renewSession=true; /* ------------------------------------------------------------ */ protected SecurityHandler() { + addBean(_authenticatorFactory); } - + /* ------------------------------------------------------------ */ /** Get the identityService. * @return the identityService */ + @Override public IdentityService getIdentityService() { return _identityService; @@ -99,6 +100,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { if (isStarted()) throw new IllegalStateException("Started"); + updateBean(_identityService,identityService); _identityService = identityService; } @@ -106,6 +108,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti /** Get the loginService. * @return the loginService */ + @Override public LoginService getLoginService() { return _loginService; @@ -119,8 +122,8 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { if (isStarted()) throw new IllegalStateException("Started"); + updateBean(_loginService,loginService); _loginService = loginService; - _loginServiceShared=false; } @@ -139,7 +142,10 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { if (isStarted()) throw new IllegalStateException("Started"); + updateBean(_authenticator,authenticator); _authenticator = authenticator; + if (_authenticator!=null) + _authMethod=_authenticator.getAuthMethod(); } /* ------------------------------------------------------------ */ @@ -160,6 +166,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { if (isRunning()) throw new IllegalStateException("running"); + updateBean(_authenticatorFactory,authenticatorFactory); _authenticatorFactory = authenticatorFactory; } @@ -167,6 +174,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti /** * @return the realmName */ + @Override public String getRealmName() { return _realmName; @@ -188,6 +196,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti /** * @return the authMethod */ + @Override public String getAuthMethod() { return _authMethod; @@ -204,7 +213,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti throw new IllegalStateException("running"); _authMethod = authMethod; } - + /* ------------------------------------------------------------ */ /** * @return True if forwards to welcome files are authenticated @@ -228,17 +237,19 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } /* ------------------------------------------------------------ */ + @Override public String getInitParameter(String key) { return _initParameters.get(key); } - + /* ------------------------------------------------------------ */ + @Override public Set<String> getInitParameterNames() { return _initParameters.keySet(); } - + /* ------------------------------------------------------------ */ /** Set an initialization parameter. * @param key @@ -252,12 +263,12 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti throw new IllegalStateException("running"); return _initParameters.put(key,value); } - + /* ------------------------------------------------------------ */ protected LoginService findLoginService() { - List<LoginService> list = getServer().getBeans(LoginService.class); - + Collection<LoginService> list = getServer().getBeans(LoginService.class); + String realm=getRealmName(); if (realm!=null) { @@ -266,18 +277,18 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti return service; } else if (list.size()==1) - return list.get(0); + return list.iterator().next(); return null; } - + /* ------------------------------------------------------------ */ protected IdentityService findIdentityService() { return getServer().getBean(IdentityService.class); } - + /* ------------------------------------------------------------ */ - /** + /** */ @Override protected void doStart() @@ -299,19 +310,20 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti //register a session listener to handle securing sessions when authentication is performed context.getContextHandler().addEventListener(new HttpSessionListener() { - + @Override public void sessionDestroyed(HttpSessionEvent se) { - } - + + @Override public void sessionCreated(HttpSessionEvent se) - { + { //if current request is authenticated, then as we have just created the session, mark it as secure, as it has not yet been returned to a user - AbstractHttpConnection connection = AbstractHttpConnection.getCurrentConnection(); - if (connection == null) + HttpChannel<?> channel = HttpChannel.getCurrentHttpChannel(); + + if (channel == null) return; - Request request = connection.getRequest(); + Request request = channel.getRequest(); if (request == null) return; @@ -322,29 +334,25 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } }); } - + // complicated resolution of login and identity service to handle // many different ways these can be constructed and injected. - + if (_loginService==null) - { - _loginService=findLoginService(); - if (_loginService!=null) - _loginServiceShared=true; - } - + setLoginService(findLoginService()); + if (_identityService==null) { if (_loginService!=null) - _identityService=_loginService.getIdentityService(); + setIdentityService(_loginService.getIdentityService()); if (_identityService==null) - _identityService=findIdentityService(); - + setIdentityService(findIdentityService()); + if (_identityService==null && _realmName!=null) - _identityService=new DefaultIdentityService(); + setIdentityService(new DefaultIdentityService()); } - + if (_loginService!=null) { if (_loginService.getIdentityService()==null) @@ -353,49 +361,22 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti throw new IllegalStateException("LoginService has different IdentityService to "+this); } - if (!_loginServiceShared && _loginService instanceof LifeCycle) - ((LifeCycle)_loginService).start(); - - if (_authenticator==null && _authenticatorFactory!=null && _identityService!=null) - { - _authenticator=_authenticatorFactory.getAuthenticator(getServer(),ContextHandler.getCurrentContext(),this, _identityService, _loginService); - if (_authenticator!=null) - _authMethod=_authenticator.getAuthMethod(); - } + Authenticator.Factory authenticatorFactory = getAuthenticatorFactory(); + if (_authenticator==null && authenticatorFactory!=null && _identityService!=null) + setAuthenticator(authenticatorFactory.getAuthenticator(getServer(),ContextHandler.getCurrentContext(),this, _identityService, _loginService)); - if (_authenticator==null) - { - if (_realmName!=null) - { - LOG.warn("No ServerAuthentication for "+this); - throw new IllegalStateException("No ServerAuthentication"); - } - } - else - { + if (_authenticator!=null) _authenticator.setConfiguration(this); - if (_authenticator instanceof LifeCycle) - ((LifeCycle)_authenticator).start(); + else if (_realmName!=null) + { + LOG.warn("No Authenticator for "+this); + throw new IllegalStateException("No Authenticator"); } super.doStart(); } /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStop() - */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - - if (!_loginServiceShared && _loginService instanceof LifeCycle) - ((LifeCycle)_loginService).stop(); - - } - - /* ------------------------------------------------------------ */ protected boolean checkSecurity(Request request) { switch(request.getDispatcherType()) @@ -404,7 +385,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti case ASYNC: return true; case FORWARD: - if (_checkWelcomeFiles && request.getAttribute("org.eclipse.jetty.server.welcome") != null) + if (isCheckWelcomeFiles() && request.getAttribute("org.eclipse.jetty.server.welcome") != null) { request.removeAttribute("org.eclipse.jetty.server.welcome"); return true; @@ -414,7 +395,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti return false; } } - + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.security.Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication() @@ -423,7 +404,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { return _renewSession; } - + /* ------------------------------------------------------------ */ /** Set renew the session on Authentication. * <p> @@ -434,7 +415,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { _renewSession=renew; } - + /* ------------------------------------------------------------ */ /* * @see org.eclipse.jetty.server.Handler#handle(java.lang.String, @@ -446,18 +427,18 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { final Response base_response = baseRequest.getResponse(); final Handler handler=getHandler(); - + if (handler==null) return; final Authenticator authenticator = _authenticator; - + if (checkSecurity(baseRequest)) { - Object constraintInfo = prepareConstraintInfo(pathInContext, baseRequest); - + RoleInfo roleInfo = prepareConstraintInfo(pathInContext, baseRequest); + // Check data constraints - if (!checkUserDataPermissions(pathInContext, baseRequest, base_response, constraintInfo)) + if (!checkUserDataPermissions(pathInContext, baseRequest, base_response, roleInfo)) { if (!baseRequest.isHandled()) { @@ -468,12 +449,12 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } // is Auth mandatory? - boolean isAuthMandatory = - isAuthMandatory(baseRequest, base_response, constraintInfo); + boolean isAuthMandatory = + isAuthMandatory(baseRequest, base_response, roleInfo); if (isAuthMandatory && authenticator==null) { - LOG.warn("No authenticator for: "+constraintInfo); + LOG.warn("No authenticator for: "+roleInfo); if (!baseRequest.isHandled()) { response.sendError(Response.SC_FORBIDDEN); @@ -481,7 +462,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } return; } - + // check authentication Object previousIdentity = null; try @@ -509,7 +490,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti if (isAuthMandatory) { - boolean authorized=checkWebResourcePermissions(pathInContext, baseRequest, base_response, constraintInfo, userAuth.getUserIdentity()); + boolean authorized=checkWebResourcePermissions(pathInContext, baseRequest, base_response, roleInfo, userAuth.getUserIdentity()); if (!authorized) { response.sendError(Response.SC_FORBIDDEN, "!role"); @@ -517,7 +498,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti return; } } - + handler.handle(pathInContext, baseRequest, request, response); if (authenticator!=null) authenticator.secureResponse(request, response, isAuthMandatory, userAuth); @@ -581,9 +562,8 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti Context context = ContextHandler.getCurrentContext(); if (context==null) return null; - - SecurityHandler security = context.getContextHandler().getChildHandlerByClass(SecurityHandler.class); - return security; + + return context.getContextHandler().getChildHandlerByClass(SecurityHandler.class); } /* ------------------------------------------------------------ */ @@ -595,7 +575,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { login_service.logout(user.getUserIdentity()); } - + IdentityService identity_service=getIdentityService(); if (identity_service!=null) { @@ -604,12 +584,12 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti identity_service.disassociate(previous); } } - + /* ------------------------------------------------------------ */ - protected abstract Object prepareConstraintInfo(String pathInContext, Request request); + protected abstract RoleInfo prepareConstraintInfo(String pathInContext, Request request); /* ------------------------------------------------------------ */ - protected abstract boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Object constraintInfo) throws IOException; + protected abstract boolean checkUserDataPermissions(String pathInContext, Request request, Response response, RoleInfo constraintInfo) throws IOException; /* ------------------------------------------------------------ */ protected abstract boolean isAuthMandatory(Request baseRequest, Response base_response, Object constraintInfo); @@ -618,7 +598,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti protected abstract boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity) throws IOException; - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ public class NotChecked implements Principal @@ -640,7 +620,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ public static Principal __NO_USER = new Principal() @@ -656,7 +636,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti return "No User"; } }; - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /** diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java index 20db84749c..1e1bd6ab96 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java @@ -19,15 +19,14 @@ package org.eclipse.jetty.security; import java.util.Properties; - import javax.security.auth.Subject; import org.eclipse.jetty.server.UserIdentity; +import org.eclipse.jetty.util.B64Code; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.security.B64Code; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; @@ -42,25 +41,25 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic protected IdentityService _identityService;// = new LdapIdentityService(); protected String _name; private String _config; - + private String _targetName; public SpnegoLoginService() { - + } - + public SpnegoLoginService( String name ) { setName(name); } - + public SpnegoLoginService( String name, String config ) { setName(name); setConfig(config); } - + public String getName() { return _name; @@ -72,38 +71,38 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic { throw new IllegalStateException("Running"); } - + _name = name; } - + public String getConfig() { return _config; } - + public void setConfig( String config ) { if (isRunning()) { throw new IllegalStateException("Running"); } - + _config = config; } - - - + + + @Override protected void doStart() throws Exception { Properties properties = new Properties(); Resource resource = Resource.newResource(_config); properties.load(resource.getInputStream()); - + _targetName = properties.getProperty("targetName"); - + LOG.debug("Target Name {}", _targetName); - + super.doStart(); } @@ -113,9 +112,9 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic public UserIdentity login(String username, Object credentials) { String encodedAuthToken = (String)credentials; - + byte[] authToken = B64Code.decode(encodedAuthToken); - + GSSManager manager = GSSManager.getInstance(); try { @@ -138,7 +137,7 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic { String clientName = gContext.getSrcName().toString(); String role = clientName.substring(clientName.indexOf('@') + 1); - + LOG.debug("SpnegoUserRealm: established a security context"); LOG.debug("Client Principal is: " + gContext.getSrcName()); LOG.debug("Server Principal is: " + gContext.getTargName()); @@ -148,7 +147,7 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic Subject subject = new Subject(); subject.getPrincipals().add(user); - + return _identityService.newUserIdentity(subject,user, new String[]{role}); } } @@ -179,7 +178,7 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic public void logout(UserIdentity user) { // TODO Auto-generated method stub - + } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java index bafc34276c..c62610b462 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java @@ -20,7 +20,6 @@ package org.eclipse.jetty.security; import java.security.Principal; import java.util.List; - import javax.security.auth.Subject; import org.eclipse.jetty.server.UserIdentity; @@ -30,15 +29,15 @@ public class SpnegoUserIdentity implements UserIdentity private Subject _subject; private Principal _principal; private List<String> _roles; - + public SpnegoUserIdentity( Subject subject, Principal principal, List<String> roles ) { _subject = subject; _principal = principal; _roles = roles; } - - + + public Subject getSubject() { return _subject; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java index aebf97395d..cdf1f1a1fb 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java @@ -20,26 +20,26 @@ package org.eclipse.jetty.security; import java.security.Principal; -import org.eclipse.jetty.util.security.B64Code; +import org.eclipse.jetty.util.B64Code; public class SpnegoUserPrincipal implements Principal { private final String _name; private byte[] _token; private String _encodedToken; - + public SpnegoUserPrincipal( String name, String encodedToken ) { _name = name; _encodedToken = encodedToken; } - + public SpnegoUserPrincipal( String name, byte[] token ) { _name = name; _token = token; } - + public String getName() { return _name; @@ -53,7 +53,7 @@ public class SpnegoUserPrincipal implements Principal } return _token; } - + public String getEncodedToken() { if ( _encodedToken == null ) @@ -61,5 +61,5 @@ public class SpnegoUserPrincipal implements Principal _encodedToken = new String(B64Code.encode(_token,true)); } return _encodedToken; - } + } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java index ec2fb04b0d..b65da3047e 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java @@ -19,13 +19,12 @@ package org.eclipse.jetty.security.authentication; import java.io.IOException; - import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.HttpHeaders; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.server.Authentication; @@ -38,17 +37,18 @@ import org.eclipse.jetty.util.security.Constraint; /** * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ */ -public class BasicAuthenticator extends LoginAuthenticator -{ +public class BasicAuthenticator extends LoginAuthenticator +{ /* ------------------------------------------------------------ */ public BasicAuthenticator() { } - + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.security.Authenticator#getAuthMethod() */ + @Override public String getAuthMethod() { return Constraint.__BASIC_AUTH; @@ -58,11 +58,12 @@ public class BasicAuthenticator extends LoginAuthenticator /** * @see org.eclipse.jetty.security.Authenticator#validateRequest(javax.servlet.ServletRequest, javax.servlet.ServletResponse, boolean) */ + @Override public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; - String credentials = request.getHeader(HttpHeaders.AUTHORIZATION); + String credentials = request.getHeader(HttpHeader.AUTHORIZATION.asString()); try { @@ -70,7 +71,7 @@ public class BasicAuthenticator extends LoginAuthenticator return new DeferredAuthentication(this); if (credentials != null) - { + { int space=credentials.indexOf(' '); if (space>0) { @@ -98,8 +99,8 @@ public class BasicAuthenticator extends LoginAuthenticator if (DeferredAuthentication.isDeferred(response)) return Authentication.UNAUTHENTICATED; - - response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "basic realm=\"" + _loginService.getName() + '"'); + + response.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), "basic realm=\"" + _loginService.getName() + '"'); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return Authentication.SEND_CONTINUE; } @@ -109,6 +110,7 @@ public class BasicAuthenticator extends LoginAuthenticator } } + @Override public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException { return true; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java index a4bef236a3..9eedbf56ce 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java @@ -24,7 +24,6 @@ import java.security.Principal; import java.security.cert.CRL; import java.security.cert.X509Certificate; import java.util.Collection; - import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; @@ -70,21 +69,23 @@ public class ClientCertAuthenticator extends LoginAuthenticator private boolean _enableOCSP = false; /** Location of OCSP Responder */ private String _ocspResponderURL; - + public ClientCertAuthenticator() { super(); } + @Override public String getAuthMethod() { return Constraint.__CERT_AUTH; } - + /** * @return Authentication for request * @throws ServerAuthException */ + @Override public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException { if (!mandatory) @@ -99,7 +100,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator // Need certificates. if (certs != null && certs.length > 0) { - + if (_validateCerts) { KeyStore trustStore = getKeyStore(null, @@ -109,7 +110,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator CertificateValidator validator = new CertificateValidator(trustStore, crls); validator.validate(certs); } - + for (X509Certificate cert: certs) { if (cert==null) @@ -135,7 +136,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator response.sendError(HttpServletResponse.SC_FORBIDDEN); return Authentication.SEND_FAILURE; } - + return Authentication.UNAUTHENTICATED; } catch (Exception e) @@ -182,6 +183,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator return CertificateUtils.loadCRL(crlPath); } + @Override public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException { return true; @@ -310,9 +312,9 @@ public class ClientCertAuthenticator extends LoginAuthenticator { _maxCertPathLength = maxCertPathLength; } - + /* ------------------------------------------------------------ */ - /** + /** * @return true if CRL Distribution Points support is enabled */ public boolean isEnableCRLDP() @@ -330,7 +332,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator } /* ------------------------------------------------------------ */ - /** + /** * @return true if On-Line Certificate Status Protocol support is enabled */ public boolean isEnableOCSP() @@ -348,7 +350,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator } /* ------------------------------------------------------------ */ - /** + /** * @return Location of the OCSP Responder */ public String getOcspResponderURL() diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index 26640168df..2cbd37f342 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -24,7 +24,6 @@ import java.io.PrintWriter; import java.util.Collection; import java.util.Collections; import java.util.Locale; - import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -60,12 +59,13 @@ public class DeferredAuthentication implements Authentication.Deferred /** * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate(ServletRequest) */ + @Override public Authentication authenticate(ServletRequest request) { try { Authentication authentication = _authenticator.validateRequest(request,__deferredResponse,true); - + if (authentication!=null && (authentication instanceof Authentication.User) && !(authentication instanceof Authentication.ResponseSent)) { LoginService login_service= _authenticator.getLoginService(); @@ -82,11 +82,12 @@ public class DeferredAuthentication implements Authentication.Deferred } return this; } - + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.server.Authentication.Deferred#authenticate(javax.servlet.ServletRequest, javax.servlet.ServletResponse) */ + @Override public Authentication authenticate(ServletRequest request, ServletResponse response) { try @@ -110,6 +111,7 @@ public class DeferredAuthentication implements Authentication.Deferred /** * @see org.eclipse.jetty.server.Authentication.Deferred#login(java.lang.String, java.lang.String) */ + @Override public Authentication login(String username, String password) { LoginService login_service= _authenticator.getLoginService(); @@ -144,152 +146,185 @@ public class DeferredAuthentication implements Authentication.Deferred { return response==__deferredResponse; } - + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ final static HttpServletResponse __deferredResponse = new HttpServletResponse() { + @Override public void addCookie(Cookie cookie) { } + @Override public void addDateHeader(String name, long date) { } + @Override public void addHeader(String name, String value) { } + @Override public void addIntHeader(String name, int value) { } + @Override public boolean containsHeader(String name) { return false; } + @Override public String encodeRedirectURL(String url) { return null; } + @Override public String encodeRedirectUrl(String url) { return null; } + @Override public String encodeURL(String url) { return null; } + @Override public String encodeUrl(String url) { return null; } + @Override public void sendError(int sc) throws IOException { } + @Override public void sendError(int sc, String msg) throws IOException { } + @Override public void sendRedirect(String location) throws IOException { } + @Override public void setDateHeader(String name, long date) { } + @Override public void setHeader(String name, String value) { } + @Override public void setIntHeader(String name, int value) { } + @Override public void setStatus(int sc) { } + @Override public void setStatus(int sc, String sm) { } + @Override public void flushBuffer() throws IOException { } + @Override public int getBufferSize() { return 1024; } + @Override public String getCharacterEncoding() { return null; } + @Override public String getContentType() { return null; } + @Override public Locale getLocale() { return null; } + @Override public ServletOutputStream getOutputStream() throws IOException { return __nullOut; } + @Override public PrintWriter getWriter() throws IOException { return IO.getNullPrintWriter(); } + @Override public boolean isCommitted() { return true; } + @Override public void reset() { } + @Override public void resetBuffer() { } + @Override public void setBufferSize(int size) { } + @Override public void setCharacterEncoding(String charset) { } + @Override public void setContentLength(int len) { } + @Override public void setContentType(String type) { } + @Override public void setLocale(Locale loc) { } + @Override public Collection<String> getHeaderNames() { return Collections.emptyList(); @@ -333,5 +368,5 @@ public class DeferredAuthentication implements Authentication.Deferred } }; - + } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index c42c26c871..8c06f06e6a 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -26,13 +26,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; - import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.HttpHeaders; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; @@ -51,8 +50,8 @@ import org.eclipse.jetty.util.security.Credential; /** * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ - * - * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} + * + * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} * using the name "maxNonceAge" */ public class DigestAuthenticator extends LoginAuthenticator @@ -88,7 +87,7 @@ public class DigestAuthenticator extends LoginAuthenticator public void setConfiguration(AuthConfiguration configuration) { super.setConfiguration(configuration); - + String mna=configuration.getInitParameter("maxNonceAge"); if (mna!=null) { @@ -98,7 +97,7 @@ public class DigestAuthenticator extends LoginAuthenticator } } } - + /* ------------------------------------------------------------ */ public synchronized void setMaxNonceAge(long maxNonceAgeInMillis) { @@ -106,18 +105,21 @@ public class DigestAuthenticator extends LoginAuthenticator } /* ------------------------------------------------------------ */ + @Override public String getAuthMethod() { return Constraint.__DIGEST_AUTH; } /* ------------------------------------------------------------ */ + @Override public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException { return true; } /* ------------------------------------------------------------ */ + @Override public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException { if (!mandatory) @@ -125,14 +127,14 @@ public class DigestAuthenticator extends LoginAuthenticator HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; - String credentials = request.getHeader(HttpHeaders.AUTHORIZATION); + String credentials = request.getHeader(HttpHeader.AUTHORIZATION.asString()); try { boolean stale = false; if (credentials != null) { - if (LOG.isDebugEnabled()) + if (LOG.isDebugEnabled()) LOG.debug("Credentials: " + credentials); QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(credentials, "=, ", true, false); final Digest digest = new Digest(request.getMethod()); @@ -174,7 +176,7 @@ public class DigestAuthenticator extends LoginAuthenticator digest.qop = tok; else if ("uri".equalsIgnoreCase(name)) digest.uri = tok; - else if ("response".equalsIgnoreCase(name)) + else if ("response".equalsIgnoreCase(name)) digest.response = tok; name=null; } @@ -192,7 +194,7 @@ public class DigestAuthenticator extends LoginAuthenticator return new UserAuthentication(getAuthMethod(),user); } } - else if (n == 0) + else if (n == 0) stale = true; } @@ -200,9 +202,9 @@ public class DigestAuthenticator extends LoginAuthenticator if (!DeferredAuthentication.isDeferred(response)) { String domain = request.getContextPath(); - if (domain == null) + if (domain == null) domain = "/"; - response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"" + _loginService.getName() + response.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), "Digest realm=\"" + _loginService.getName() + "\", domain=\"" + domain + "\", nonce=\"" @@ -227,7 +229,7 @@ public class DigestAuthenticator extends LoginAuthenticator public String newNonce(Request request) { Nonce nonce; - + do { byte[] nounce = new byte[24]; @@ -237,7 +239,7 @@ public class DigestAuthenticator extends LoginAuthenticator } while (_nonceCount.putIfAbsent(nonce._nonce,nonce)!=null); _nonceQueue.add(nonce); - + return nonce._nonce; } @@ -255,7 +257,7 @@ public class DigestAuthenticator extends LoginAuthenticator { expired = request.getTimeStamp()-_maxNonceAgeMs; } - + Nonce nonce=_nonceQueue.peek(); while (nonce!=null && nonce._ts<expired) { @@ -263,14 +265,14 @@ public class DigestAuthenticator extends LoginAuthenticator _nonceCount.remove(nonce._nonce); nonce=_nonceQueue.peek(); } - - + + try { nonce = _nonceCount.get(digest.nonce); if (nonce==null) return 0; - + long count = Long.parseLong(digest.nc,16); if (count>Integer.MAX_VALUE) return 0; @@ -279,7 +281,7 @@ public class DigestAuthenticator extends LoginAuthenticator old=nonce._nc.get(); if (count<=old) return -1; - + return 1; } catch (Exception e) diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 829a9d595b..3ad5a9c127 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -21,7 +21,6 @@ package org.eclipse.jetty.security.authentication; import java.io.IOException; import java.util.Collections; import java.util.Enumeration; - import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -32,14 +31,15 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import javax.servlet.http.HttpSession; -import org.eclipse.jetty.http.HttpHeaders; -import org.eclipse.jetty.http.HttpMethods; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpHeaderValue; +import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; -import org.eclipse.jetty.server.AbstractHttpConnection; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Authentication.User; +import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.MultiMap; @@ -51,18 +51,18 @@ import org.eclipse.jetty.util.security.Constraint; /** * FORM Authenticator. - * + * * <p>This authenticator implements form authentication will use dispatchers to * the login page if the {@link #__FORM_DISPATCH} init parameter is set to true. * Otherwise it will redirect.</p> - * + * * <p>The form authenticator redirects unauthenticated requests to a log page * which should use a form to gather username/password from the user and send them - * to the /j_security_check URI within the context. FormAuthentication uses + * to the /j_security_check URI within the context. FormAuthentication uses * {@link SessionAuthentication} to wrap Authentication results so that they * are associated with the session.</p> - * - * + * + * */ public class FormAuthenticator extends LoginAuthenticator { @@ -98,7 +98,7 @@ public class FormAuthenticator extends LoginAuthenticator setErrorPage(error); _dispatch=dispatch; } - + /* ------------------------------------------------------------ */ /** * If true, uris that cause a redirect to a login page will always @@ -111,14 +111,14 @@ public class FormAuthenticator extends LoginAuthenticator { _alwaysSaveUri = alwaysSave; } - - + + /* ------------------------------------------------------------ */ public boolean getAlwaysSaveUri () { return _alwaysSaveUri; } - + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.security.authentication.LoginAuthenticator#setConfiguration(org.eclipse.jetty.security.Authenticator.AuthConfiguration) @@ -138,6 +138,7 @@ public class FormAuthenticator extends LoginAuthenticator } /* ------------------------------------------------------------ */ + @Override public String getAuthMethod() { return Constraint.__FORM_AUTH; @@ -153,7 +154,7 @@ public class FormAuthenticator extends LoginAuthenticator } _formLoginPage = path; _formLoginPath = path; - if (_formLoginPath.indexOf('?') > 0) + if (_formLoginPath.indexOf('?') > 0) _formLoginPath = _formLoginPath.substring(0, _formLoginPath.indexOf('?')); } @@ -175,14 +176,15 @@ public class FormAuthenticator extends LoginAuthenticator _formErrorPage = path; _formErrorPath = path; - if (_formErrorPath.indexOf('?') > 0) + if (_formErrorPath.indexOf('?') > 0) _formErrorPath = _formErrorPath.substring(0, _formErrorPath.indexOf('?')); } } /* ------------------------------------------------------------ */ + @Override public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException - { + { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; String uri = request.getRequestURI(); @@ -197,7 +199,7 @@ public class FormAuthenticator extends LoginAuthenticator return new DeferredAuthentication(this); HttpSession session = request.getSession(true); - + try { // Handle a request for authentication. @@ -205,14 +207,16 @@ public class FormAuthenticator extends LoginAuthenticator { final String username = request.getParameter(__J_USERNAME); final String password = request.getParameter(__J_PASSWORD); - + UserIdentity user = _loginService.login(username,password); + LOG.debug("jsecuritycheck {} {}",username,user); if (user!=null) { session=renewSession(request,response); - + // Redirect to original request String nuri; + FormAuthentication form_auth; synchronized(session) { nuri = (String) session.getAttribute(__J_URI); @@ -220,81 +224,91 @@ public class FormAuthenticator extends LoginAuthenticator if (nuri == null || nuri.length() == 0) { nuri = request.getContextPath(); - if (nuri.length() == 0) + if (nuri.length() == 0) nuri = URIUtil.SLASH; } Authentication cached=new SessionAuthentication(getAuthMethod(),user,password); session.setAttribute(SessionAuthentication.__J_AUTHENTICATED, cached); + form_auth = new FormAuthentication(getAuthMethod(),user); } - response.setContentLength(0); + LOG.debug("authenticated {}->{}",form_auth,nuri); + + response.setContentLength(0); response.sendRedirect(response.encodeRedirectURL(nuri)); - - return new FormAuthentication(getAuthMethod(),user); + return form_auth; } - + // not authenticated - if (LOG.isDebugEnabled()) + if (LOG.isDebugEnabled()) LOG.debug("Form authentication FAILED for " + StringUtil.printable(username)); if (_formErrorPage == null) { - if (response != null) + LOG.debug("auth failed {}->403",username); + if (response != null) response.sendError(HttpServletResponse.SC_FORBIDDEN); } else if (_dispatch) { + LOG.debug("auth failed {}=={}",username,_formErrorPage); RequestDispatcher dispatcher = request.getRequestDispatcher(_formErrorPage); - response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache"); - response.setDateHeader(HttpHeaders.EXPIRES,1); + response.setHeader(HttpHeader.CACHE_CONTROL.asString(),HttpHeaderValue.NO_CACHE.asString()); + response.setDateHeader(HttpHeader.EXPIRES.asString(),1); dispatcher.forward(new FormRequest(request), new FormResponse(response)); } else { + LOG.debug("auth failed {}->{}",username,_formErrorPage); response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(),_formErrorPage))); } - + return Authentication.SEND_FAILURE; } - + // Look for cached authentication Authentication authentication = (Authentication) session.getAttribute(SessionAuthentication.__J_AUTHENTICATED); - if (authentication != null) + if (authentication != null) { // Has authentication been revoked? - if (authentication instanceof Authentication.User && + if (authentication instanceof Authentication.User && _loginService!=null && !_loginService.validate(((Authentication.User)authentication).getUserIdentity())) { - + LOG.debug("auth revoked {}",authentication); session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); } else { - String j_uri=(String)session.getAttribute(__J_URI); - if (j_uri!=null) + synchronized (session) { - MultiMap<String> j_post = (MultiMap<String>)session.getAttribute(__J_POST); - if (j_post!=null) + String j_uri=(String)session.getAttribute(__J_URI); + if (j_uri!=null) { - StringBuffer buf = request.getRequestURL(); - if (request.getQueryString() != null) - buf.append("?").append(request.getQueryString()); - - if (j_uri.equals(buf.toString())) + LOG.debug("auth retry {}->{}",authentication,j_uri); + MultiMap<String> j_post = (MultiMap<String>)session.getAttribute(__J_POST); + if (j_post!=null) { - // This is a retry of an original POST request - // so restore method and parameters + LOG.debug("auth rePOST {}->{}",authentication,j_uri); + StringBuffer buf = request.getRequestURL(); + if (request.getQueryString() != null) + buf.append("?").append(request.getQueryString()); + + if (j_uri.equals(buf.toString())) + { + // This is a retry of an original POST request + // so restore method and parameters - session.removeAttribute(__J_POST); - Request base_request = (req instanceof Request)?(Request)req:AbstractHttpConnection.getCurrentConnection().getRequest(); - base_request.setMethod(HttpMethods.POST); - base_request.setParameters(j_post); + session.removeAttribute(__J_POST); + Request base_request = HttpChannel.getCurrentHttpChannel().getRequest(); + base_request.setMethod(HttpMethod.POST,HttpMethod.POST.asString()); + base_request.setParameters(j_post); + } } + else + session.removeAttribute(__J_URI); } - else - session.removeAttribute(__J_URI); - } + LOG.debug("auth {}",authentication); return authentication; } } @@ -311,52 +325,48 @@ public class FormAuthenticator extends LoginAuthenticator { // But only if it is not set already, or we save every uri that leads to a login form redirect if (session.getAttribute(__J_URI)==null || _alwaysSaveUri) - { + { StringBuffer buf = request.getRequestURL(); if (request.getQueryString() != null) buf.append("?").append(request.getQueryString()); session.setAttribute(__J_URI, buf.toString()); - - if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(req.getContentType()) && HttpMethods.POST.equals(request.getMethod())) + + if (MimeTypes.Type.FORM_ENCODED.is(req.getContentType()) && HttpMethod.POST.is(request.getMethod())) { - Request base_request = (req instanceof Request)?(Request)req:AbstractHttpConnection.getCurrentConnection().getRequest(); - base_request.extractParameters(); + Request base_request = (req instanceof Request)?(Request)req:HttpChannel.getCurrentHttpChannel().getRequest(); + base_request.extractParameters(); session.setAttribute(__J_POST, new MultiMap<String>(base_request.getParameters())); } } } - + // send the the challenge if (_dispatch) { + LOG.debug("challenge {}=={}",session.getId(),_formLoginPage); RequestDispatcher dispatcher = request.getRequestDispatcher(_formLoginPage); - response.setHeader(HttpHeaders.CACHE_CONTROL,"No-cache"); - response.setDateHeader(HttpHeaders.EXPIRES,1); + response.setHeader(HttpHeader.CACHE_CONTROL.asString(),HttpHeaderValue.NO_CACHE.asString()); + response.setDateHeader(HttpHeader.EXPIRES.asString(),1); dispatcher.forward(new FormRequest(request), new FormResponse(response)); } else { + LOG.debug("challenge {}->{}",session.getId(),_formLoginPage); response.sendRedirect(response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(),_formLoginPage))); } return Authentication.SEND_CONTINUE; - - - } - catch (IOException e) - { - throw new ServerAuthException(e); } - catch (ServletException e) + catch (IOException | ServletException e) { throw new ServerAuthException(e); } } - + /* ------------------------------------------------------------ */ public boolean isJSecurityCheck(String uri) { int jsc = uri.indexOf(__J_SECURITY_CHECK); - + if (jsc<0) return false; int e=jsc+__J_SECURITY_CHECK.length(); @@ -365,14 +375,15 @@ public class FormAuthenticator extends LoginAuthenticator char c = uri.charAt(e); return c==';'||c=='#'||c=='/'||c=='?'; } - + /* ------------------------------------------------------------ */ public boolean isLoginOrErrorPage(String pathInContext) { return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath)); } - + /* ------------------------------------------------------------ */ + @Override public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException { return true; @@ -394,7 +405,7 @@ public class FormAuthenticator extends LoginAuthenticator return -1; return super.getDateHeader(name); } - + @Override public String getHeader(String name) { @@ -404,16 +415,16 @@ public class FormAuthenticator extends LoginAuthenticator } @Override - public Enumeration getHeaderNames() + public Enumeration<String> getHeaderNames() { return Collections.enumeration(Collections.list(super.getHeaderNames())); } @Override - public Enumeration getHeaders(String name) + public Enumeration<String> getHeaders(String name) { if (name.toLowerCase().startsWith("if-")) - return Collections.enumeration(Collections.EMPTY_LIST); + return Collections.<String>enumeration(Collections.<String>emptyList()); return super.getHeaders(name); } } @@ -447,30 +458,30 @@ public class FormAuthenticator extends LoginAuthenticator if (notIgnored(name)) super.setDateHeader(name,date); } - + @Override public void setHeader(String name, String value) { if (notIgnored(name)) super.setHeader(name,value); } - + private boolean notIgnored(String name) { - if (HttpHeaders.CACHE_CONTROL.equalsIgnoreCase(name) || - HttpHeaders.PRAGMA.equalsIgnoreCase(name) || - HttpHeaders.ETAG.equalsIgnoreCase(name) || - HttpHeaders.EXPIRES.equalsIgnoreCase(name) || - HttpHeaders.LAST_MODIFIED.equalsIgnoreCase(name) || - HttpHeaders.AGE.equalsIgnoreCase(name)) + if (HttpHeader.CACHE_CONTROL.is(name) || + HttpHeader.PRAGMA.is(name) || + HttpHeader.ETAG.is(name) || + HttpHeader.EXPIRES.is(name) || + HttpHeader.LAST_MODIFIED.is(name) || + HttpHeader.AGE.is(name)) return false; return true; } } - + /* ------------------------------------------------------------ */ /** This Authentication represents a just completed Form authentication. - * Subsequent requests from the same user are authenticated by the presents + * Subsequent requests from the same user are authenticated by the presents * of a {@link SessionAuthentication} instance in their session. */ public static class FormAuthentication extends UserAuthentication implements Authentication.ResponseSent @@ -479,7 +490,7 @@ public class FormAuthenticator extends LoginAuthenticator { super(method,userIdentity); } - + @Override public String toString() { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index 17e86574b6..44c571e7db 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -26,9 +26,13 @@ import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.session.AbstractSessionManager; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public abstract class LoginAuthenticator implements Authenticator { + private static final Logger LOG = Log.getLogger(LoginAuthenticator.class); + protected LoginService _loginService; protected IdentityService _identityService; private boolean _renewSession; @@ -37,6 +41,7 @@ public abstract class LoginAuthenticator implements Authenticator { } + @Override public void setConfiguration(AuthConfiguration configuration) { _loginService=configuration.getLoginService(); @@ -47,12 +52,12 @@ public abstract class LoginAuthenticator implements Authenticator throw new IllegalStateException("No IdentityService for "+this+" in "+configuration); _renewSession=configuration.isSessionRenewedOnAuthentication(); } - + public LoginService getLoginService() { return _loginService; } - + /** Change the session id. * The session is changed to a new instance with a new ID if and only if:<ul> * <li>A session exists. @@ -66,14 +71,19 @@ public abstract class LoginAuthenticator implements Authenticator protected HttpSession renewSession(HttpServletRequest request, HttpServletResponse response) { HttpSession httpSession = request.getSession(false); - - //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users - //(indicated by SESSION_SECURED not being set on the session) then we should change id - if (_renewSession && httpSession!=null && httpSession.getAttribute(AbstractSessionManager.SESSION_KNOWN_ONLY_TO_AUTHENTICATED)!=Boolean.TRUE) + + if (_renewSession && httpSession!=null) { - synchronized (this) + synchronized (httpSession) { - httpSession = AbstractSessionManager.renewSession(request, httpSession,true); + //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users + //(indicated by SESSION_SECURED not being set on the session) then we should change id + if (httpSession.getAttribute(AbstractSessionManager.SESSION_KNOWN_ONLY_TO_AUTHENTICATED)!=Boolean.TRUE) + { + HttpSession newSession = AbstractSessionManager.renewSession(request, httpSession,true); + LOG.debug("renew {}->{}",httpSession.getId(),newSession.getId()); + httpSession=newSession; + } } } return httpSession; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java index e90ddd58e6..27fa01f8ab 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java @@ -19,14 +19,13 @@ package org.eclipse.jetty.security.authentication; import java.security.Principal; - import javax.security.auth.Subject; /** * This is similar to the jaspi PasswordValidationCallback but includes user * principal and group info as well. - * + * * @version $Rev: 4792 $ $Date: 2009-03-18 22:55:52 +0100 (Wed, 18 Mar 2009) $ */ public interface LoginCallback @@ -36,7 +35,7 @@ public interface LoginCallback public String getUserName(); public Object getCredential(); - + public boolean isSuccess(); public void setSuccess(boolean success); @@ -46,10 +45,10 @@ public interface LoginCallback public void setUserPrincipal(Principal userPrincipal); public String[] getRoles(); - + public void setRoles(String[] roles); - + public void clearPassword(); - + } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java index 82c74a4192..003ccbd09c 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java @@ -19,7 +19,6 @@ package org.eclipse.jetty.security.authentication; import java.security.Principal; - import javax.security.auth.Subject; import org.eclipse.jetty.security.IdentityService; @@ -27,7 +26,7 @@ import org.eclipse.jetty.security.IdentityService; /** * This is similar to the jaspi PasswordValidationCallback but includes user * principal and group info as well. - * + * * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ */ public class LoginCallbackImpl implements LoginCallback diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java index 260d5ddd3f..9e94282364 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -22,7 +22,6 @@ package org.eclipse.jetty.security.authentication; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; - import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionBindingEvent; @@ -44,17 +43,17 @@ public class SessionAuthentication implements Authentication.User, Serializable, private static final long serialVersionUID = -4643200685888258706L; - + public final static String __J_AUTHENTICATED="org.eclipse.jetty.security.UserIdentity"; private final String _method; private final String _name; private final Object _credentials; - + private transient UserIdentity _userIdentity; private transient HttpSession _session; - + public SessionAuthentication(String method, UserIdentity userIdentity, Object credentials) { _method = method; @@ -78,30 +77,30 @@ public class SessionAuthentication implements Authentication.User, Serializable, return _userIdentity.isUserInRole(role, scope); } - private void readObject(ObjectInputStream stream) - throws IOException, ClassNotFoundException + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { stream.defaultReadObject(); - + SecurityHandler security=SecurityHandler.getCurrentSecurityHandler(); if (security==null) throw new IllegalStateException("!SecurityHandler"); LoginService login_service=security.getLoginService(); if (login_service==null) throw new IllegalStateException("!LoginService"); - + _userIdentity=login_service.login(_name,_credentials); LOG.debug("Deserialized and relogged in {}",this); } - + public void logout() { if (_session!=null && _session.getAttribute(__J_AUTHENTICATED)!=null) _session.removeAttribute(__J_AUTHENTICATED); - else + else doLogout(); } - + private void doLogout() { SecurityHandler security=SecurityHandler.getCurrentSecurityHandler(); @@ -110,18 +109,20 @@ public class SessionAuthentication implements Authentication.User, Serializable, if (_session!=null) _session.removeAttribute(AbstractSessionManager.SESSION_KNOWN_ONLY_TO_AUTHENTICATED); } - + @Override public String toString() { - return "Session"+super.toString(); + return String.format("%s@%x{%s,%s}",this.getClass().getSimpleName(),hashCode(),_session==null?"-":_session.getId(),_userIdentity); } + @Override public void sessionWillPassivate(HttpSessionEvent se) { } + @Override public void sessionDidActivate(HttpSessionEvent se) { if (_session==null) @@ -130,6 +131,7 @@ public class SessionAuthentication implements Authentication.User, Serializable, } } + @Override public void valueBound(HttpSessionBindingEvent event) { if (_session==null) @@ -138,9 +140,10 @@ public class SessionAuthentication implements Authentication.User, Serializable, } } + @Override public void valueUnbound(HttpSessionBindingEvent event) { doLogout(); } - -}
\ No newline at end of file + +} diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java index ca5563f4e5..2981e18fab 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java @@ -19,13 +19,12 @@ package org.eclipse.jetty.security.authentication; import java.io.IOException; - import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jetty.http.HttpHeaders; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.server.Authentication; @@ -38,14 +37,12 @@ import org.eclipse.jetty.util.security.Constraint; public class SpnegoAuthenticator extends LoginAuthenticator { private static final Logger LOG = Log.getLogger(SpnegoAuthenticator.class); - private String _authMethod = Constraint.__SPNEGO_AUTH; - + public SpnegoAuthenticator() { - } - + /** * Allow for a custom authMethod value to be set for instances where SPENGO may not be appropriate * @param authMethod @@ -54,24 +51,26 @@ public class SpnegoAuthenticator extends LoginAuthenticator { _authMethod = authMethod; } - + + @Override public String getAuthMethod() { return _authMethod; } + @Override public Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException - { + { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse res = (HttpServletResponse)response; - - String header = req.getHeader(HttpHeaders.AUTHORIZATION); + + String header = req.getHeader(HttpHeader.AUTHORIZATION.asString()); if (!mandatory) { return new DeferredAuthentication(this); } - + // check to see if we have authorization headers required to continue if ( header == null ) { @@ -81,32 +80,33 @@ public class SpnegoAuthenticator extends LoginAuthenticator { return Authentication.UNAUTHENTICATED; } - + LOG.debug("SpengoAuthenticator: sending challenge"); - res.setHeader(HttpHeaders.WWW_AUTHENTICATE, HttpHeaders.NEGOTIATE); + res.setHeader(HttpHeader.WWW_AUTHENTICATE.asString(), HttpHeader.NEGOTIATE.asString()); res.sendError(HttpServletResponse.SC_UNAUTHORIZED); return Authentication.SEND_CONTINUE; - } + } catch (IOException ioe) { throw new ServerAuthException(ioe); - } + } } - else if (header != null && header.startsWith(HttpHeaders.NEGOTIATE)) + else if (header != null && header.startsWith(HttpHeader.NEGOTIATE.asString())) { String spnegoToken = header.substring(10); - + UserIdentity user = _loginService.login(null,spnegoToken); - + if ( user != null ) { return new UserAuthentication(getAuthMethod(),user); } } - + return Authentication.UNAUTHENTICATED; } + @Override public boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, User validatedUser) throws ServerAuthException { return true; |