diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java index 820a074edab..f36ae623ac1 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticator.java @@ -15,7 +15,7 @@ package org.eclipse.jetty.security.jaspi; import java.security.Principal; import java.util.Map; -import java.util.Set; +import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.message.AuthException; @@ -26,13 +26,11 @@ import javax.security.auth.message.config.ServerAuthConfig; import javax.security.auth.message.config.ServerAuthContext; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.ServerAuthException; -import org.eclipse.jetty.security.authentication.FormAuthenticator; +import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.authentication.DeferredAuthenticator; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.UserIdentity; @@ -43,28 +41,27 @@ import org.eclipse.jetty.server.Authentication.User; */ public class JaspiAuthenticator implements Authenticator { - private final String _authContextId; private final ServerAuthConfig _authConfig; private final Map _authProperties; private final ServletCallbackHandler _callbackHandler; private final Subject _serviceSubject; private final boolean _allowLazyAuthentication; + private final IdentityService _identityService; - - public JaspiAuthenticator(String authContextId, ServerAuthConfig authConfig, Map authProperties, ServletCallbackHandler callbackHandler, - Subject serviceSubject, boolean allowLazyAuthentication) + public JaspiAuthenticator(ServerAuthConfig authConfig, Map authProperties, ServletCallbackHandler callbackHandler, + Subject serviceSubject, boolean allowLazyAuthentication, IdentityService identityService) { // TODO maybe pass this in via setConfiguration ? if (callbackHandler == null) throw new NullPointerException("No CallbackHandler"); if (authConfig == null) throw new NullPointerException("No AuthConfig"); - this._authContextId = authContextId; this._authConfig = authConfig; this._authProperties = authProperties; this._callbackHandler = callbackHandler; this._serviceSubject = serviceSubject; this._allowLazyAuthentication = allowLazyAuthentication; + this._identityService = identityService; } @@ -83,7 +80,7 @@ public class JaspiAuthenticator implements Authenticator if (_allowLazyAuthentication && !mandatory) return new DeferredAuthenticator.DeferredAuthentication(this,request,response); - JaspiMessageInfo info = new JaspiMessageInfo((HttpServletRequest)request,(HttpServletResponse)response,mandatory); + JaspiMessageInfo info = new JaspiMessageInfo(request, response, mandatory); request.setAttribute("org.eclipse.jetty.security.jaspi.info",info); return validateRequest(info); } @@ -92,8 +89,7 @@ public class JaspiAuthenticator implements Authenticator public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, User validatedUser) throws ServerAuthException { JaspiMessageInfo info = (JaspiMessageInfo)req.getAttribute("org.eclipse.jetty.security.jaspi.info"); - if (info==null) - info = new JaspiMessageInfo((HttpServletRequest)req,(HttpServletResponse)res,mandatory); + if (info==null) throw new NullPointerException("MeesageInfo from request missing: " + req); return secureResponse(info,validatedUser); } @@ -101,30 +97,59 @@ public class JaspiAuthenticator implements Authenticator { try { - ServerAuthContext authContext = _authConfig.getAuthContext(_authContextId,_serviceSubject,_authProperties); + String authContextId = _authConfig.getAuthContextID(messageInfo); + ServerAuthContext authContext = _authConfig.getAuthContext(authContextId,_serviceSubject,_authProperties); Subject clientSubject = new Subject(); AuthStatus authStatus = authContext.validateRequest(messageInfo,clientSubject,_serviceSubject); - String authMethod = (String)messageInfo.getMap().get(JaspiMessageInfo.AUTH_METHOD_KEY); - CallerPrincipalCallback principalCallback = _callbackHandler.getThreadCallerPrincipalCallback(); - Principal principal = principalCallback == null?null:principalCallback.getPrincipal(); - GroupPrincipalCallback groupPrincipalCallback = _callbackHandler.getThreadGroupPrincipalCallback(); - String[] groups = groupPrincipalCallback == null?null:groupPrincipalCallback.getGroups(); - +// String authMethod = (String)messageInfo.getMap().get(JaspiMessageInfo.AUTH_METHOD_KEY); + if (authStatus == AuthStatus.SEND_CONTINUE) - return Authentication.CHALLENGE; + return Authentication.SEND_CONTINUE; if (authStatus == AuthStatus.SEND_FAILURE) - return Authentication.FAILURE; + return Authentication.SEND_FAILURE; - Set ids = clientSubject.getPrivateCredentials(UserIdentity.class); - if (ids.size()>0) + if (authStatus == AuthStatus.SUCCESS) { - if (authStatus == AuthStatus.SEND_SUCCESS) - return new FormAuthenticator.FormAuthentication(this,ids.iterator().next()); - return new UserAuthentication(this,ids.iterator().next()); + Set ids = clientSubject.getPrivateCredentials(UserIdentity.class); + UserIdentity userIdentity; + if (ids.size() > 0) { + userIdentity = ids.iterator().next(); +// return new FormAuthenticator.FormAuthentication(this,ids.iterator().next()); + } else { + CallerPrincipalCallback principalCallback = _callbackHandler.getThreadCallerPrincipalCallback(); + if (principalCallback == null) throw new NullPointerException("No CallerPrincipalCallback"); + Principal principal = principalCallback.getPrincipal(); + if (principal == null) { + String principalName = principalCallback.getName(); + Set principals = principalCallback.getSubject().getPrincipals(); + for (Principal p: principals) + { + if (p.getName().equals(principalName)) + { + principal = p; + break; + } + } + if (principal == null) + { + return Authentication.UNAUTHENTICATED; + } + } + GroupPrincipalCallback groupPrincipalCallback = _callbackHandler.getThreadGroupPrincipalCallback(); + String[] groups = groupPrincipalCallback == null ? null : groupPrincipalCallback.getGroups(); + userIdentity = _identityService.newUserIdentity(clientSubject, principal, groups); + } + return new UserAuthentication(this, userIdentity); } - return Authentication.FAILURE; + if (authStatus == AuthStatus.SEND_SUCCESS) + { + //we are processing a message in a secureResponse dialog. + return Authentication.SEND_SUCCESS; + } + //should not happen + throw new NullPointerException("No AuthStatus returned"); } catch (AuthException e) { @@ -136,10 +161,11 @@ public class JaspiAuthenticator implements Authenticator { try { - ServerAuthContext authContext = _authConfig.getAuthContext(_authContextId,_serviceSubject,_authProperties); + String authContextId = _authConfig.getAuthContextID(messageInfo); + ServerAuthContext authContext = _authConfig.getAuthContext(authContextId,_serviceSubject,_authProperties); // TODO authContext.cleanSubject(messageInfo,validatedUser.getUserIdentity().getSubject()); AuthStatus status = authContext.secureResponse(messageInfo,_serviceSubject); - return (AuthStatus.SUCCESS.equals(status)); + return (AuthStatus.SEND_SUCCESS.equals(status)); } catch (AuthException e) { diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java index c1229458652..badfbffe51d 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiAuthenticatorFactory.java @@ -30,6 +30,7 @@ import javax.servlet.ServletContext; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.DefaultAuthenticatorFactory; import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.Authenticator.Configuration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.log.Log; @@ -79,7 +80,7 @@ public class JaspiAuthenticatorFactory extends DefaultAuthenticatorFactory } /* ------------------------------------------------------------ */ - protected Authenticator newAuthenticator(Server server, ServletContext context, Configuration configuration, LoginService loginService) + public Authenticator getAuthenticator(Server server, ServletContext context, Configuration configuration, IdentityService identityService, LoginService loginService) { Authenticator authenticator=null; try @@ -106,9 +107,9 @@ public class JaspiAuthenticatorFactory extends DefaultAuthenticatorFactory Map map = new HashMap(); for (String key : configuration.getInitParameterNames()) map.put(key,configuration.getInitParameter(key)); - authenticator= new JaspiAuthenticator(appContext,serverAuthConfig,map,servletCallbackHandler, + authenticator= new JaspiAuthenticator(serverAuthConfig,map,servletCallbackHandler, serviceSubject, - configuration.isLazy()); + configuration.isLazy(), identityService); } } } diff --git a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java index f691ef24128..fb992dde4f4 100644 --- a/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java +++ b/jetty-jaspi/src/main/java/org/eclipse/jetty/security/jaspi/JaspiMessageInfo.java @@ -105,8 +105,8 @@ public class JaspiMessageInfo implements MessageInfo public boolean containsKey(Object key) { - if (MANDATORY_KEY.equals(key)) return true; - if (AUTH_METHOD_KEY.equals(key)) return true; + if (MANDATORY_KEY.equals(key)) return isMandatory; + if (AUTH_METHOD_KEY.equals(key)) return authMethod != null; return delegate != null && delegate.containsKey(key); } @@ -204,11 +204,13 @@ public class JaspiMessageInfo implements MessageInfo return delegate; } - boolean isAuthMandatory() { + boolean isAuthMandatory() + { return isMandatory; } - String getAuthMethod() { + String getAuthMethod() + { return authMethod; } } 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 33a60f47ea8..bfd2c0e4629 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 @@ -100,6 +100,6 @@ public interface Authenticator */ interface Factory { - Authenticator getAuthenticator(Server server, ServletContext context, Configuration configuration); + Authenticator getAuthenticator(Server server, ServletContext context, Configuration configuration, IdentityService identityService, LoginService loginService); } } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java index 83fc0257af4..9cf0db08781 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java @@ -46,7 +46,7 @@ public class DefaultAuthenticatorFactory implements Authenticator.Factory { LoginService _loginService; - public Authenticator getAuthenticator(Server server, ServletContext context, Configuration configuration) + public Authenticator getAuthenticator(Server server, ServletContext context, Configuration configuration, IdentityService identityService, LoginService loginService) { String auth=configuration.getAuthMethod(); Authenticator authenticator=null; 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 2dcc7ddb1e5..de58139352d 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 @@ -319,12 +319,12 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti if (_authenticator==null && _authenticatorFactory!=null && _identityService!=null) { - _authenticator=_authenticatorFactory.getAuthenticator(getServer(),ContextHandler.getCurrentContext(),this); + _authenticator=_authenticatorFactory.getAuthenticator(getServer(),ContextHandler.getCurrentContext(),this, _identityService, _loginService); if (_authenticator!=null) _authMethod=_authenticator.getAuthMethod(); } - if (_authenticator==null) + if (_authenticator==null) { if (_realmName!=null) { @@ -338,7 +338,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti if (_authenticator instanceof LifeCycle) ((LifeCycle)_authenticator).start(); } - + super.doStart(); } @@ -415,8 +415,8 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti Authentication authentication = base_request.getAuthentication(); if (authentication==null || authentication==Authentication.NOT_CHECKED) authentication=authenticator.validateRequest(request, response, isAuthMandatory); - - + + if (authentication instanceof Authentication.ResponseSent) { base_request.setHandled(true); @@ -425,14 +425,17 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti { Authentication.User userAuth = (Authentication.User)authentication; base_request.setAuthentication(authentication); - _identityService.associate(userAuth.getUserIdentity()); - - boolean authorized=checkWebResourcePermissions(pathInContext, base_request, base_response, constraintInfo, userAuth.getUserIdentity()); - if (isAuthMandatory && !authorized) + _identityService.associate(userAuth.getUserIdentity()); + + if (isAuthMandatory) { - response.sendError(Response.SC_FORBIDDEN, "!role"); - base_request.setHandled(true); - return; + boolean authorized=checkWebResourcePermissions(pathInContext, base_request, base_response, constraintInfo, userAuth.getUserIdentity()); + if (!authorized) + { + response.sendError(Response.SC_FORBIDDEN, "!role"); + base_request.setHandled(true); + return; + } } handler.handle(pathInContext, request, response); @@ -443,7 +446,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti DeferredAuthentication lazy= (DeferredAuthentication)authentication; lazy.setIdentityService(_identityService); base_request.setAuthentication(authentication); - + try { handler.handle(pathInContext, request, response); @@ -476,7 +479,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } finally { - _identityService.associate(null); + _identityService.associate(null); } } else 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 472a189d572..8032419a555 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 @@ -24,7 +24,6 @@ import org.eclipse.jetty.http.HttpHeaders; import org.eclipse.jetty.http.security.B64Code; import org.eclipse.jetty.http.security.Constraint; import org.eclipse.jetty.security.UserAuthentication; -import org.eclipse.jetty.security.DefaultUserIdentity; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.UserIdentity; @@ -82,7 +81,7 @@ public class BasicAuthenticator extends LoginAuthenticator { response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "basic realm=\"" + _loginService.getName() + '"'); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return Authentication.CHALLENGE; + return Authentication.SEND_CONTINUE; } return credentials==null?Authentication.NOT_CHECKED:Authentication.UNAUTHENTICATED; } 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 e21d9001ddb..0f765ce47ec 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 @@ -84,7 +84,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator if (mandatory) { response.sendError(HttpServletResponse.SC_FORBIDDEN); - return Authentication.FAILURE; + return Authentication.SEND_FAILURE; } return certs==null?Authentication.NOT_CHECKED:Authentication.UNAUTHENTICATED; 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 8df5c72a3dc..d2c5a3ce504 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,7 +26,6 @@ import org.eclipse.jetty.http.security.B64Code; import org.eclipse.jetty.http.security.Constraint; import org.eclipse.jetty.http.security.Credential; import org.eclipse.jetty.security.UserAuthentication; -import org.eclipse.jetty.security.DefaultUserIdentity; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Request; @@ -145,7 +144,7 @@ public class DigestAuthenticator extends LoginAuthenticator + (_useStale ? (" stale=" + stale) : "")); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return Authentication.CHALLENGE; + return Authentication.SEND_CONTINUE; } return credentials==null?Authentication.NOT_CHECKED:Authentication.UNAUTHENTICATED; 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 8b70f6dad29..77d23fc2bad 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 @@ -14,11 +14,8 @@ package org.eclipse.jetty.security.authentication; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Enumeration; -import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -212,7 +209,7 @@ public class FormAuthenticator extends LoginAuthenticator response.sendRedirect(URIUtil.addPaths(request.getContextPath(),_formErrorPage)); } - return Authentication.FAILURE; + return Authentication.SEND_FAILURE; } if (mandatory) @@ -242,7 +239,7 @@ public class FormAuthenticator extends LoginAuthenticator { response.sendRedirect(URIUtil.addPaths(request.getContextPath(),_formLoginPage)); } - return Authentication.CHALLENGE; + return Authentication.SEND_CONTINUE; } return Authentication.UNAUTHENTICATED; diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java index f0e1b456ff7..14b723bd569 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Authentication.java @@ -29,7 +29,7 @@ import javax.servlet.ServletResponse; public interface Authentication { - + /* ------------------------------------------------------------ */ /** A successful Authentication with User information. */ @@ -99,6 +99,10 @@ public interface Authentication { } + public interface SendSuccess extends ResponseSent + { + } + /* ------------------------------------------------------------ */ /** Unauthenticated state. *

@@ -120,12 +124,13 @@ public interface Authentication *

* This convenience instance is for when an authentication challenge has been sent. */ - public final static Authentication CHALLENGE = new Authentication.Challenge(){public String toString(){return "CHALLENGE";}}; + public final static Authentication SEND_CONTINUE = new Authentication.Challenge(){public String toString(){return "CHALLENGE";}}; /* ------------------------------------------------------------ */ /** Authentication failure sent. *

* This convenience instance is for when an authentication failure has been sent. */ - public final static Authentication FAILURE = new Authentication.Failure(){public String toString(){return "FAILURE";}}; + public final static Authentication SEND_FAILURE = new Authentication.Failure(){public String toString(){return "FAILURE";}}; + public final static Authentication SEND_SUCCESS = new SendSuccess(){public String toString(){return "SEND_SUCCESS";}}; }