Bug 275396 Fix a lot of little jaspi problems. Still problems with Request methods

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@208 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
David Jencks 2009-05-08 00:41:07 +00:00
parent ab24a94666
commit 08938580c3
11 changed files with 97 additions and 65 deletions

View File

@ -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<UserIdentity> 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<UserIdentity> 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<Principal> 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)
{

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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.
* <p>
@ -120,12 +124,13 @@ public interface Authentication
* <p>
* 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.
* <p>
* 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";}};
}