reworked the Authentication to better support lazyness and to move towards servlet 3.0 login and logout
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@151 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
5e11796031
commit
3a129bb90f
|
@ -2,6 +2,8 @@ jetty-7.0.0.M1-SNAPSHOT
|
|||
+ 271258 FORM Authentication dispatch handling avoids caching
|
||||
+ Initial support for LoginService.logout
|
||||
+ Removed HTTPConnection specifics from connection dispatching
|
||||
+ JETTY-695 Handler dump
|
||||
+ Reworked lazy authentication
|
||||
|
||||
jetty-7.0.0.M0
|
||||
+ JETTY-496 Support inetd/xinetd through use of System.inheritedChannel()
|
||||
|
|
|
@ -71,6 +71,7 @@ public class ManyContexts
|
|||
server.setHandler(contexts);
|
||||
|
||||
server.start();
|
||||
System.err.println(server.dump());
|
||||
server.join();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.jetty.server.Server;
|
|||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
|
||||
|
@ -40,17 +41,16 @@ public class ManyServletContexts
|
|||
server.setHandler(contexts);
|
||||
|
||||
ServletContextHandler root = new ServletContextHandler(contexts,"/",ServletContextHandler.SESSIONS);
|
||||
root.addServlet(new ServletHolder(new HelloServlet("Ciao")), "/*");
|
||||
root.addServlet(new ServletHolder(new HelloServlet("Hello")), "/");
|
||||
root.addServlet(new ServletHolder(new HelloServlet("Ciao")), "/it/*");
|
||||
root.addServlet(new ServletHolder(new HelloServlet("Bonjoir")), "/fr/*");
|
||||
|
||||
ServletContextHandler other = new ServletContextHandler(contexts,"/other",ServletContextHandler.SESSIONS);
|
||||
other.addServlet("org.eclipse.jetty.server.example.ManyServletServletContextHandlers$HelloServlet", "/*");
|
||||
|
||||
StatisticsHandler stats = new StatisticsHandler();
|
||||
contexts.addHandler(stats);
|
||||
ServletContextHandler yetanother =new ServletContextHandler(stats,"/yo",ServletContextHandler.SESSIONS);
|
||||
yetanother.addServlet(new ServletHolder(new HelloServlet("YO!")), "/*");
|
||||
other.addServlet(DefaultServlet.class.getCanonicalName(), "/");
|
||||
other.addServlet(new ServletHolder(new HelloServlet("YO!")), "*.yo");
|
||||
|
||||
server.start();
|
||||
System.err.println(server.dump());
|
||||
server.join();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
package org.eclipse.jetty.http.security;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
@ -82,7 +83,10 @@ public abstract class Credential
|
|||
|
||||
public boolean check(Object credentials)
|
||||
{
|
||||
if (!(credentials instanceof String) && !(credentials instanceof Password)) Log.warn("Can't check " + credentials.getClass() + " against CRYPT");
|
||||
if (credentials instanceof char[])
|
||||
credentials=new String((char[])credentials);
|
||||
if (!(credentials instanceof String) && !(credentials instanceof Password))
|
||||
Log.warn("Can't check " + credentials.getClass() + " against CRYPT");
|
||||
|
||||
String passwd = credentials.toString();
|
||||
return _cooked.equals(UnixCrypt.crypt(passwd, _cooked));
|
||||
|
|
|
@ -98,9 +98,11 @@ public class Password extends Credential
|
|||
/* ------------------------------------------------------------ */
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o) return true;
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (null == o) return false;
|
||||
if (null == o)
|
||||
return false;
|
||||
|
||||
if (o instanceof Password)
|
||||
{
|
||||
|
@ -108,7 +110,8 @@ public class Password extends Credential
|
|||
return p._pw == _pw || (null != _pw && _pw.equals(p._pw));
|
||||
}
|
||||
|
||||
if (o instanceof String) return o.equals(_pw);
|
||||
if (o instanceof String)
|
||||
return o.equals(_pw);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jetty-jaspi</artifactId>
|
||||
<name>Jetty :: Security</name>
|
||||
<name>Jetty :: JASPI Security</name>
|
||||
<description>Jetty security infrastructure</description>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -50,21 +50,36 @@
|
|||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>repository.apache.org</id>
|
||||
<name>Apache Snapshot Repository</name>
|
||||
<layout>default</layout>
|
||||
<url>http://repository.apache.org/content/groups/snapshots/</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-security</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jaspi_1.0_spec</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jaspi_1.0_spec</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -87,10 +87,11 @@ public class JaspiAuthenticator implements Authenticator
|
|||
}
|
||||
|
||||
// most likely validatedUser is not needed here.
|
||||
public Authentication.Status secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication 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)
|
||||
info = new JaspiMessageInfo((HttpServletRequest)req,(HttpServletResponse)res,mandatory);
|
||||
return secureResponse(info,validatedUser);
|
||||
}
|
||||
|
||||
|
@ -108,10 +109,20 @@ public class JaspiAuthenticator implements Authenticator
|
|||
GroupPrincipalCallback groupPrincipalCallback = _callbackHandler.getThreadGroupPrincipalCallback();
|
||||
String[] groups = groupPrincipalCallback == null?null:groupPrincipalCallback.getGroups();
|
||||
|
||||
|
||||
if (authStatus == AuthStatus.SEND_CONTINUE)
|
||||
return Authentication.CHALLENGE;
|
||||
if (authStatus == AuthStatus.SEND_FAILURE)
|
||||
return Authentication.FAILED;
|
||||
|
||||
Set<UserIdentity> ids = clientSubject.getPrivateCredentials(UserIdentity.class);
|
||||
if (ids.size()>0)
|
||||
return new DefaultAuthentication(toServerAuthStatus(authStatus),authMethod,ids.iterator().next());
|
||||
return Authentication.SEND_FAILURE_RESULTS;
|
||||
{
|
||||
if (authStatus == AuthStatus.SEND_SUCCESS)
|
||||
return new DefaultAuthentication.Send(this,ids.iterator().next());
|
||||
return new DefaultAuthentication(this,ids.iterator().next());
|
||||
}
|
||||
return Authentication.FAILED;
|
||||
}
|
||||
catch (AuthException e)
|
||||
{
|
||||
|
@ -119,31 +130,19 @@ public class JaspiAuthenticator implements Authenticator
|
|||
}
|
||||
}
|
||||
|
||||
public Authentication.Status secureResponse(JaspiMessageInfo messageInfo, Authentication validatedUser) throws ServerAuthException
|
||||
public boolean secureResponse(JaspiMessageInfo messageInfo, Authentication validatedUser) throws ServerAuthException
|
||||
{
|
||||
try
|
||||
{
|
||||
ServerAuthContext authContext = _authConfig.getAuthContext(_authContextId,_serviceSubject,_authProperties);
|
||||
authContext.cleanSubject(messageInfo,validatedUser.getUserIdentity().getSubject());
|
||||
return toServerAuthStatus(authContext.secureResponse(messageInfo,_serviceSubject));
|
||||
AuthStatus status = authContext.secureResponse(messageInfo,_serviceSubject);
|
||||
return (AuthStatus.SUCCESS.equals(status));
|
||||
}
|
||||
catch (AuthException e)
|
||||
{
|
||||
throw new ServerAuthException(e);
|
||||
}
|
||||
}
|
||||
|
||||
Authentication.Status toServerAuthStatus(AuthStatus authStatus) throws ServerAuthException
|
||||
{
|
||||
if (authStatus == AuthStatus.SEND_CONTINUE)
|
||||
return Authentication.Status.SEND_CONTINUE;
|
||||
if (authStatus == AuthStatus.SEND_FAILURE)
|
||||
return Authentication.Status.SEND_FAILURE;
|
||||
if (authStatus == AuthStatus.SEND_SUCCESS)
|
||||
return Authentication.Status.SEND_SUCCESS;
|
||||
if (authStatus == AuthStatus.SUCCESS)
|
||||
return Authentication.Status.SUCCESS;
|
||||
throw new ServerAuthException("Invalid server status: " + authStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,49 +22,99 @@ import org.eclipse.jetty.server.UserIdentity;
|
|||
*/
|
||||
public interface Authentication
|
||||
{
|
||||
public enum Status
|
||||
{
|
||||
SEND_FAILURE(false), SEND_SUCCESS(true), SEND_CONTINUE(false), SUCCESS(true);
|
||||
boolean _success;
|
||||
Status(boolean success) {_success=success; }
|
||||
public boolean isSuccess(){ return _success;}
|
||||
}
|
||||
|
||||
Status getAuthStatus();
|
||||
|
||||
String getAuthMethod();
|
||||
|
||||
UserIdentity getUserIdentity();
|
||||
|
||||
boolean isSuccess();
|
||||
|
||||
boolean isSend();
|
||||
|
||||
void logout();
|
||||
|
||||
|
||||
public static final Authentication SUCCESS_UNAUTH_RESULTS = new Authentication()
|
||||
public static final Authentication FAILED = new Authentication()
|
||||
{
|
||||
public String getAuthMethod() {return null;}
|
||||
public Status getAuthStatus() {return Authentication.Status.SUCCESS;}
|
||||
public UserIdentity getUserIdentity() {return UserIdentity.UNAUTHENTICATED_IDENTITY;}
|
||||
public boolean isSuccess() {return true;}
|
||||
public void logout() {}
|
||||
public String getAuthMethod()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public UserIdentity getUserIdentity()
|
||||
{
|
||||
return UserIdentity.UNAUTHENTICATED_IDENTITY;
|
||||
}
|
||||
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSend()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void logout()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static final Authentication SEND_CONTINUE_RESULTS = new Authentication()
|
||||
public static final Authentication CHALLENGE = new Authentication()
|
||||
{
|
||||
public String getAuthMethod() {return null;}
|
||||
public Status getAuthStatus() {return Authentication.Status.SEND_CONTINUE;}
|
||||
public UserIdentity getUserIdentity() {return UserIdentity.UNAUTHENTICATED_IDENTITY;}
|
||||
public boolean isSuccess() {return false;}
|
||||
public void logout() {}
|
||||
public String getAuthMethod()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public UserIdentity getUserIdentity()
|
||||
{
|
||||
return UserIdentity.UNAUTHENTICATED_IDENTITY;
|
||||
}
|
||||
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSend()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void logout()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static final Authentication SEND_FAILURE_RESULTS = new Authentication()
|
||||
public static final Authentication NOT_CHECKED = new Authentication()
|
||||
{
|
||||
public String getAuthMethod() {return null;}
|
||||
public Status getAuthStatus() {return Authentication.Status.SEND_FAILURE;}
|
||||
public UserIdentity getUserIdentity() {return UserIdentity.UNAUTHENTICATED_IDENTITY;}
|
||||
public boolean isSuccess() {return false;}
|
||||
public void logout() {}
|
||||
public String getAuthMethod()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public UserIdentity getUserIdentity()
|
||||
{
|
||||
return UserIdentity.UNAUTHENTICATED_IDENTITY;
|
||||
}
|
||||
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSend()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void logout()
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public interface Authenticator
|
|||
String getAuthMethod();
|
||||
|
||||
Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException;
|
||||
Authentication.Status secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, Authentication validatedUser) throws ServerAuthException;
|
||||
boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, Authentication validatedUser) throws ServerAuthException;
|
||||
|
||||
interface Configuration
|
||||
{
|
||||
|
|
|
@ -187,9 +187,9 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
|
|||
UserDataConstraint userDataConstraint = UserDataConstraint.get(constraint.getDataConstraint());
|
||||
roleInfo.setUserDataConstraint(userDataConstraint);
|
||||
|
||||
boolean unchecked = !constraint.getAuthenticate();
|
||||
roleInfo.setUnchecked(unchecked);
|
||||
if (!roleInfo.isUnchecked())
|
||||
boolean checked = constraint.getAuthenticate();
|
||||
roleInfo.setChecked(checked);
|
||||
if (roleInfo.isChecked())
|
||||
{
|
||||
if (constraint.isAnyRole())
|
||||
{
|
||||
|
@ -312,7 +312,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
|
|||
{
|
||||
return false;
|
||||
}
|
||||
return !((RoleInfo)constraintInfo).isUnchecked();
|
||||
return ((RoleInfo)constraintInfo).isChecked();
|
||||
}
|
||||
|
||||
protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity)
|
||||
|
@ -324,7 +324,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
|
|||
}
|
||||
RoleInfo roleInfo = (RoleInfo)constraintInfo;
|
||||
|
||||
if (roleInfo.isUnchecked())
|
||||
if (!roleInfo.isChecked())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -23,13 +23,11 @@ import org.eclipse.jetty.server.UserIdentity;
|
|||
*/
|
||||
public class DefaultAuthentication implements Authentication
|
||||
{
|
||||
private final Authentication.Status _authStatus;
|
||||
private final Authenticator _authenticator;
|
||||
private final UserIdentity _userIdentity;
|
||||
|
||||
public DefaultAuthentication(Authentication.Status authStatus, Authenticator authenticator, UserIdentity userIdentity)
|
||||
public DefaultAuthentication(Authenticator authenticator, UserIdentity userIdentity)
|
||||
{
|
||||
_authStatus = authStatus;
|
||||
_authenticator = authenticator;
|
||||
_userIdentity=userIdentity;
|
||||
}
|
||||
|
@ -38,11 +36,6 @@ public class DefaultAuthentication implements Authentication
|
|||
{
|
||||
return _authenticator.getAuthMethod();
|
||||
}
|
||||
|
||||
public Authentication.Status getAuthStatus()
|
||||
{
|
||||
return _authStatus;
|
||||
}
|
||||
|
||||
public UserIdentity getUserIdentity()
|
||||
{
|
||||
|
@ -51,7 +44,12 @@ public class DefaultAuthentication implements Authentication
|
|||
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return _authStatus.isSuccess();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isSend()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void logout()
|
||||
|
@ -75,6 +73,19 @@ public class DefaultAuthentication implements Authentication
|
|||
|
||||
public String toString()
|
||||
{
|
||||
return "{Auth,"+getAuthMethod()+","+_authStatus+","+","+_userIdentity+"}";
|
||||
return "{Auth,"+getAuthMethod()+","+_userIdentity+"}";
|
||||
}
|
||||
|
||||
public static class Send extends DefaultAuthentication
|
||||
{
|
||||
public Send(Authenticator authenticator, UserIdentity userIdentity)
|
||||
{
|
||||
super(authenticator,userIdentity);
|
||||
}
|
||||
|
||||
public boolean isSend()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public class DefaultIdentityService implements IdentityService
|
|||
* 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)}
|
||||
*/
|
||||
public UserIdentity associate(UserIdentity user, Scope scope)
|
||||
public UserIdentity scope(UserIdentity user, Scope scope)
|
||||
{
|
||||
Map<String,String> roleRefMap=scope.getRoleRefMap();
|
||||
if (roleRefMap!=null && roleRefMap.size()>0)
|
||||
|
@ -51,16 +51,16 @@ public class DefaultIdentityService implements IdentityService
|
|||
return user;
|
||||
}
|
||||
|
||||
public void disassociate(UserIdentity scoped)
|
||||
public void descope(UserIdentity scoped)
|
||||
{
|
||||
}
|
||||
|
||||
public Object associateRunAs(UserIdentity user, RunAsToken token)
|
||||
public Object setRunAs(UserIdentity user, RunAsToken token)
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public void disassociateRunAs(Object lastToken)
|
||||
public void unsetRunAs(Object lastToken)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -94,11 +94,6 @@ public class DefaultIdentityService implements IdentityService
|
|||
_delegate=user;
|
||||
_roleRefMap=roleRefMap;
|
||||
}
|
||||
|
||||
public String[] getRoles()
|
||||
{
|
||||
return _delegate.getRoles();
|
||||
}
|
||||
|
||||
public Subject getSubject()
|
||||
{
|
||||
|
|
|
@ -37,11 +37,6 @@ public class DefaultUserIdentity implements UserIdentity
|
|||
_roles=roles;
|
||||
}
|
||||
|
||||
public String[] getRoles()
|
||||
{
|
||||
return _roles;
|
||||
}
|
||||
|
||||
public Subject getSubject()
|
||||
{
|
||||
return _subject;
|
||||
|
|
|
@ -160,7 +160,7 @@ public class HashLoginService extends MappedLoginService
|
|||
|
||||
if (username != null && username.length() > 0 && credentials != null && credentials.length() > 0)
|
||||
{
|
||||
String[] roleArray = UserIdentity.NO_ROLES;
|
||||
String[] roleArray = IdentityService.NO_ROLES;
|
||||
if (roles != null && roles.length() > 0)
|
||||
roleArray = roles.split(",");
|
||||
known.add(username);
|
||||
|
|
|
@ -26,7 +26,8 @@ import org.eclipse.jetty.server.UserIdentity;
|
|||
*/
|
||||
public interface IdentityService
|
||||
{
|
||||
|
||||
final static String[] NO_ROLES = new String[]{};
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -42,13 +43,13 @@ public interface IdentityService
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Associate the {@link UserIdentity} and {@link UserIdentity.Scope}
|
||||
* with the current thread.
|
||||
* Scope the {@link UserIdentity} to a {@link UserIdentity.Scope}.
|
||||
* @see IdentityService#descope(UserIdentity)
|
||||
* @param user The current user.
|
||||
* @param context The new scope.
|
||||
* @return A scoped {@link UserIdentity}.
|
||||
*/
|
||||
UserIdentity associate(UserIdentity user, UserIdentity.Scope context);
|
||||
UserIdentity scope(UserIdentity user, UserIdentity.Scope context);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -56,7 +57,7 @@ public interface IdentityService
|
|||
* previousUser identity.
|
||||
* @param scoped UserIdentity returned from previous associate call
|
||||
*/
|
||||
void disassociate(UserIdentity scoped);
|
||||
void descope(UserIdentity scoped);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -64,7 +65,7 @@ public interface IdentityService
|
|||
* @param token The runAsToken to associate.
|
||||
* @return The previous runAsToken or null.
|
||||
*/
|
||||
Object associateRunAs(UserIdentity user, RunAsToken token);
|
||||
Object setRunAs(UserIdentity user, RunAsToken token);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -72,7 +73,7 @@ public interface IdentityService
|
|||
* and reassociate the previous token.
|
||||
* @param token RUNAS returned from previous associateRunAs call
|
||||
*/
|
||||
void disassociateRunAs(Object token);
|
||||
void unsetRunAs(Object token);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
|
|
@ -13,32 +13,39 @@
|
|||
|
||||
package org.eclipse.jetty.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.security.auth.Subject;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
/**
|
||||
* @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $
|
||||
*/
|
||||
public class LazyAuthentication implements Authentication
|
||||
{
|
||||
private static final Subject unauthenticatedSubject = new Subject();
|
||||
|
||||
private final Authenticator _serverAuthentication;
|
||||
private final ServletRequest _request;
|
||||
private final ServletResponse _response;
|
||||
protected final Authenticator _authenticator;
|
||||
protected final ServletRequest _request;
|
||||
protected final ServletResponse _response;
|
||||
|
||||
private Authentication _delegate;
|
||||
|
||||
public LazyAuthentication(Authenticator serverAuthentication, ServletRequest request, ServletResponse response)
|
||||
public LazyAuthentication(Authenticator authenticator, ServletRequest request, ServletResponse response)
|
||||
{
|
||||
if (serverAuthentication == null) throw new NullPointerException("No ServerAuthentication");
|
||||
this._serverAuthentication = serverAuthentication;
|
||||
this._request=request;
|
||||
this._response=response;
|
||||
if (authenticator == null)
|
||||
throw new NullPointerException("No Authenticator");
|
||||
this._authenticator = authenticator;
|
||||
this._request = request;
|
||||
this._response = response;
|
||||
}
|
||||
|
||||
private Authentication getDelegate()
|
||||
|
@ -47,36 +54,32 @@ public class LazyAuthentication implements Authentication
|
|||
{
|
||||
try
|
||||
{
|
||||
_delegate = _serverAuthentication.validateRequest(_request, _response, false);
|
||||
_delegate = _authenticator.validateRequest(_request,__nullResponse,false);
|
||||
if (_delegate.isSend())
|
||||
_delegate=Authentication.NOT_CHECKED;
|
||||
}
|
||||
catch (ServerAuthException e)
|
||||
{
|
||||
_delegate = DefaultAuthentication.SEND_FAILURE_RESULTS;
|
||||
Log.debug(e);
|
||||
_delegate = Authentication.FAILED;
|
||||
}
|
||||
}
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
public Authentication.Status getAuthStatus()
|
||||
{
|
||||
return getDelegate().getAuthStatus();
|
||||
}
|
||||
|
||||
public boolean isSuccess()
|
||||
{
|
||||
return getDelegate().isSuccess();
|
||||
}
|
||||
|
||||
public void logout()
|
||||
public boolean isSend()
|
||||
{
|
||||
if (_delegate!=null)
|
||||
_delegate.logout();
|
||||
return false;
|
||||
}
|
||||
|
||||
// for cleaning in secureResponse
|
||||
|
||||
public UserIdentity getUserIdentity()
|
||||
{
|
||||
return _delegate == null ? UserIdentity.UNAUTHENTICATED_IDENTITY: _delegate.getUserIdentity();
|
||||
return getDelegate().getUserIdentity();
|
||||
}
|
||||
|
||||
public String getAuthMethod()
|
||||
|
@ -84,8 +87,173 @@ public class LazyAuthentication implements Authentication
|
|||
return getDelegate().getAuthMethod();
|
||||
}
|
||||
|
||||
public void logout()
|
||||
{
|
||||
if (_delegate != null)
|
||||
_delegate.logout();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "{Lazy,"+_delegate+"}";
|
||||
return "{Lazy," + _delegate + "}";
|
||||
}
|
||||
|
||||
private static HttpServletResponse __nullResponse = new HttpServletResponse()
|
||||
{
|
||||
public void addCookie(Cookie cookie)
|
||||
{
|
||||
}
|
||||
|
||||
public void addDateHeader(String name, long date)
|
||||
{
|
||||
}
|
||||
|
||||
public void addHeader(String name, String value)
|
||||
{
|
||||
}
|
||||
|
||||
public void addIntHeader(String name, int value)
|
||||
{
|
||||
}
|
||||
|
||||
public boolean containsHeader(String name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public String encodeRedirectURL(String url)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public String encodeRedirectUrl(String url)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public String encodeURL(String url)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public String encodeUrl(String url)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public void sendError(int sc) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public void sendError(int sc, String msg) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public void sendRedirect(String location) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public void setDateHeader(String name, long date)
|
||||
{
|
||||
}
|
||||
|
||||
public void setHeader(String name, String value)
|
||||
{
|
||||
}
|
||||
|
||||
public void setIntHeader(String name, int value)
|
||||
{
|
||||
}
|
||||
|
||||
public void setStatus(int sc)
|
||||
{
|
||||
}
|
||||
|
||||
public void setStatus(int sc, String sm)
|
||||
{
|
||||
}
|
||||
|
||||
public void flushBuffer() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public int getBufferSize()
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
|
||||
public String getCharacterEncoding()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getContentType()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Locale getLocale()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public ServletOutputStream getOutputStream() throws IOException
|
||||
{
|
||||
return __nullOut;
|
||||
}
|
||||
|
||||
public PrintWriter getWriter() throws IOException
|
||||
{
|
||||
return IO.getNullPrintWriter();
|
||||
}
|
||||
|
||||
public boolean isCommitted()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
}
|
||||
|
||||
public void resetBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
public void setBufferSize(int size)
|
||||
{
|
||||
}
|
||||
|
||||
public void setCharacterEncoding(String charset)
|
||||
{
|
||||
}
|
||||
|
||||
public void setContentLength(int len)
|
||||
{
|
||||
}
|
||||
|
||||
public void setContentType(String type)
|
||||
{
|
||||
}
|
||||
|
||||
public void setLocale(Locale loc)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private static ServletOutputStream __nullOut = new ServletOutputStream()
|
||||
{
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public void print(String s) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
public void println(String s) throws IOException
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
|
|||
subject.getPrincipals().add(userPrincipal);
|
||||
subject.getPrivateCredentials().add(credential);
|
||||
subject.setReadOnly();
|
||||
identity=_identityService.newUserIdentity(subject,userPrincipal,UserIdentity.NO_ROLES);
|
||||
identity=_identityService.newUserIdentity(subject,userPrincipal,IdentityService.NO_ROLES);
|
||||
}
|
||||
|
||||
_users.put(userName,identity);
|
||||
|
|
|
@ -29,21 +29,25 @@ public class RoleInfo
|
|||
{
|
||||
private final static String[] NO_ROLES={};
|
||||
private boolean _isAnyRole;
|
||||
private boolean _unchecked;
|
||||
private boolean _checked;
|
||||
private boolean _forbidden;
|
||||
private UserDataConstraint _userDataConstraint;
|
||||
|
||||
private String[] _roles = NO_ROLES;
|
||||
|
||||
public boolean isUnchecked()
|
||||
public RoleInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public boolean isChecked()
|
||||
{
|
||||
return _unchecked;
|
||||
return _checked;
|
||||
}
|
||||
|
||||
public void setUnchecked(boolean unchecked)
|
||||
public void setChecked(boolean checked)
|
||||
{
|
||||
this._unchecked = unchecked;
|
||||
if (unchecked)
|
||||
this._checked = checked;
|
||||
if (!checked)
|
||||
{
|
||||
_forbidden=false;
|
||||
_roles=NO_ROLES;
|
||||
|
@ -61,7 +65,7 @@ public class RoleInfo
|
|||
this._forbidden = forbidden;
|
||||
if (forbidden)
|
||||
{
|
||||
_unchecked = false;
|
||||
_checked = true;
|
||||
_userDataConstraint = null;
|
||||
_isAnyRole=false;
|
||||
_roles=NO_ROLES;
|
||||
|
@ -78,7 +82,7 @@ public class RoleInfo
|
|||
this._isAnyRole=anyRole;
|
||||
if (anyRole)
|
||||
{
|
||||
_unchecked = false;
|
||||
_checked = true;
|
||||
_roles=NO_ROLES;
|
||||
}
|
||||
}
|
||||
|
@ -115,8 +119,8 @@ public class RoleInfo
|
|||
{
|
||||
if (other._forbidden)
|
||||
setForbidden(true);
|
||||
else if (other._unchecked)
|
||||
setUnchecked(true);
|
||||
else if (!other._checked) // TODO is this the right way around???
|
||||
setChecked(true);
|
||||
else if (other._isAnyRole)
|
||||
setAnyRole(true);
|
||||
else if (!_isAnyRole)
|
||||
|
@ -130,6 +134,6 @@ public class RoleInfo
|
|||
|
||||
public String toString()
|
||||
{
|
||||
return "{RoleInfo"+(_forbidden?",F":"")+(_unchecked?",U":"")+(_isAnyRole?",*":Arrays.asList(_roles).toString())+"}";
|
||||
return "{RoleInfo"+(_forbidden?",F":"")+(_checked?",C":"")+(_isAnyRole?",*":Arrays.asList(_roles).toString())+"}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -413,7 +413,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti
|
|||
final Authenticator authenticator = _authenticator;
|
||||
Authentication authentication = authenticator.validateRequest(request, response, isAuthMandatory);
|
||||
|
||||
if (authentication.getAuthStatus() == Authentication.Status.SUCCESS)
|
||||
if (authentication!=null && !authentication.isSend())
|
||||
{
|
||||
final UserIdentity user_identity=authentication.getUserIdentity();
|
||||
base_request.setAuthType(authentication.getAuthMethod());
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.eclipse.jetty.security.Authentication;
|
|||
import org.eclipse.jetty.security.DefaultAuthentication;
|
||||
import org.eclipse.jetty.security.DefaultUserIdentity;
|
||||
import org.eclipse.jetty.security.ServerAuthException;
|
||||
import org.eclipse.jetty.security.Authentication.Status;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
|
@ -75,18 +74,15 @@ public class BasicAuthenticator extends LoginAuthenticator
|
|||
|
||||
UserIdentity user = _loginService.login(username,password);
|
||||
if (user!=null)
|
||||
{
|
||||
return new DefaultAuthentication(Authentication.Status.SUCCESS,this,user);
|
||||
}
|
||||
return new DefaultAuthentication(this,user);
|
||||
}
|
||||
|
||||
if (!mandatory)
|
||||
{
|
||||
return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS;
|
||||
}
|
||||
return Authentication.NOT_CHECKED;
|
||||
|
||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "basic realm=\"" + _loginService.getName() + '"');
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return DefaultAuthentication.SEND_CONTINUE_RESULTS;
|
||||
return Authentication.CHALLENGE;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -94,12 +90,10 @@ public class BasicAuthenticator extends LoginAuthenticator
|
|||
}
|
||||
}
|
||||
|
||||
// most likely validatedUser is not needed here.
|
||||
|
||||
// corrct?
|
||||
public Authentication.Status secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
// TODO most likely validatedUser is not needed here ??
|
||||
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
{
|
||||
return Authentication.Status.SUCCESS;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,9 +62,8 @@ public class ClientCertAuthenticator extends LoginAuthenticator
|
|||
// Need certificates.
|
||||
if (certs == null || certs.length == 0 || certs[0] == null)
|
||||
{
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN,
|
||||
"A client certificate is required for accessing this web application but the server's listener is not configured for mutual authentication (or the client did not provide a certificate).");
|
||||
return DefaultAuthentication.SEND_FAILURE_RESULTS;
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN,"!certificate");
|
||||
return Authentication.FAILED;
|
||||
}
|
||||
|
||||
Principal principal = certs[0].getSubjectDN();
|
||||
|
@ -76,14 +75,12 @@ public class ClientCertAuthenticator extends LoginAuthenticator
|
|||
|
||||
UserIdentity user = _loginService.login(username,credential);
|
||||
if (user!=null)
|
||||
return new DefaultAuthentication(Authentication.Status.SUCCESS,this,user);
|
||||
return new DefaultAuthentication(this,user);
|
||||
|
||||
if (!mandatory)
|
||||
{
|
||||
return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS;
|
||||
}
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN, "The provided client certificate does not correspond to a trusted user.");
|
||||
return DefaultAuthentication.SEND_FAILURE_RESULTS;
|
||||
return Authentication.NOT_CHECKED;
|
||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||
return Authentication.FAILED;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -91,8 +88,8 @@ public class ClientCertAuthenticator extends LoginAuthenticator
|
|||
}
|
||||
}
|
||||
|
||||
public Authentication.Status secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
{
|
||||
return Authentication.Status.SUCCESS;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class DelegateAuthenticator implements Authenticator
|
|||
return _delegate.validateRequest(request, response, manditory);
|
||||
}
|
||||
|
||||
public Authentication.Status secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
{
|
||||
return _delegate.secureResponse(req,res, mandatory, validatedUser);
|
||||
}
|
||||
|
|
|
@ -55,9 +55,9 @@ public class DigestAuthenticator extends LoginAuthenticator
|
|||
return Constraint.__DIGEST_AUTH;
|
||||
}
|
||||
|
||||
public Authentication.Status secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
{
|
||||
return Authentication.Status.SUCCESS;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException
|
||||
|
@ -124,25 +124,29 @@ public class DigestAuthenticator extends LoginAuthenticator
|
|||
UserIdentity user = _loginService.login(digest.username,digest);
|
||||
if (user!=null)
|
||||
{
|
||||
return new DefaultAuthentication(Authentication.Status.SUCCESS,this,user);
|
||||
return new DefaultAuthentication(this,user);
|
||||
}
|
||||
}
|
||||
else if (n == 0) stale = true;
|
||||
|
||||
}
|
||||
|
||||
if (!mandatory) { return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS; }
|
||||
if (!mandatory)
|
||||
return Authentication.NOT_CHECKED;
|
||||
|
||||
String domain = request.getContextPath();
|
||||
if (domain == null) domain = "/";
|
||||
if (domain == null)
|
||||
domain = "/";
|
||||
response.setHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"" + _loginService.getName()
|
||||
+ "\", domain=\""
|
||||
+ domain
|
||||
+ "\", nonce=\""
|
||||
+ newNonce((Request)request)
|
||||
+ "\", algorithm=MD5, qop=\"auth\""
|
||||
+ (_useStale ? (" stale=" + stale) : ""));
|
||||
+ "\", domain=\""
|
||||
+ domain
|
||||
+ "\", nonce=\""
|
||||
+ newNonce((Request)request)
|
||||
+ "\", algorithm=MD5, qop=\"auth\""
|
||||
+ (_useStale ? (" stale=" + stale) : ""));
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
return DefaultAuthentication.SEND_CONTINUE_RESULTS;
|
||||
|
||||
return Authentication.CHALLENGE;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
|
|
@ -150,41 +150,49 @@ public class FormAuthenticator extends LoginAuthenticator
|
|||
HttpServletResponse response = (HttpServletResponse)res;
|
||||
HttpSession session = request.getSession(mandatory);
|
||||
String uri = request.getPathInfo();
|
||||
// not mandatory and not authenticated
|
||||
|
||||
// not mandatory or not authenticated
|
||||
if (session == null || isLoginOrErrorPage(uri))
|
||||
{
|
||||
return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS;
|
||||
return Authentication.NOT_CHECKED;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// Handle a request for authentication.
|
||||
// TODO perhaps j_securitycheck can be uri suffix?
|
||||
if (uri.endsWith(__J_SECURITY_CHECK))
|
||||
if (uri==null)
|
||||
uri=URIUtil.SLASH;
|
||||
else if (uri.endsWith(__J_SECURITY_CHECK))
|
||||
{
|
||||
final String username = request.getParameter(__J_USERNAME);
|
||||
final char[] password = request.getParameter(__J_PASSWORD).toCharArray();
|
||||
final String password = request.getParameter(__J_PASSWORD);
|
||||
|
||||
UserIdentity user = _loginService.login(username,password);
|
||||
if (user!=null)
|
||||
{
|
||||
// Redirect to original request
|
||||
String nuri = (String) session.getAttribute(__J_URI);
|
||||
String nuri;
|
||||
synchronized(session)
|
||||
{
|
||||
nuri = (String) session.getAttribute(__J_URI);
|
||||
session.removeAttribute(__J_URI);
|
||||
}
|
||||
|
||||
if (nuri == null || nuri.length() == 0)
|
||||
{
|
||||
nuri = request.getContextPath();
|
||||
if (nuri.length() == 0) nuri = URIUtil.SLASH;
|
||||
if (nuri.length() == 0)
|
||||
nuri = URIUtil.SLASH;
|
||||
}
|
||||
// TODO shouldn't we forward to original URI instead?
|
||||
session.removeAttribute(__J_URI); // Remove popped return URI.
|
||||
response.setContentLength(0);
|
||||
response.sendRedirect(response.encodeRedirectURL(nuri));
|
||||
return new DefaultAuthentication(Authentication.Status.SEND_SUCCESS,this,user);
|
||||
return new DefaultAuthentication.Send(this,user);
|
||||
}
|
||||
|
||||
// not authenticated
|
||||
if (Log.isDebugEnabled()) Log.debug("Form authentication FAILED for " + StringUtil.printable(username));
|
||||
if (Log.isDebugEnabled())
|
||||
Log.debug("Form authentication FAILED for " + StringUtil.printable(username));
|
||||
if (_formErrorPage == null)
|
||||
{
|
||||
if (response != null)
|
||||
|
@ -202,27 +210,28 @@ public class FormAuthenticator extends LoginAuthenticator
|
|||
response.sendRedirect(URIUtil.addPaths(request.getContextPath(),_formErrorPage));
|
||||
}
|
||||
|
||||
// TODO is this correct response if isMandatory false??? Can
|
||||
// that occur?
|
||||
return DefaultAuthentication.SEND_FAILURE_RESULTS;
|
||||
return Authentication.FAILED;
|
||||
}
|
||||
// Check if the session is already authenticated.
|
||||
|
||||
// Don't authenticate authform or errorpage
|
||||
if (!mandatory)
|
||||
// TODO verify this is correct action
|
||||
return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS;
|
||||
if (!mandatory)
|
||||
return Authentication.NOT_CHECKED;
|
||||
|
||||
// redirect to login page
|
||||
if (request.getQueryString() != null)
|
||||
uri += "?" + request.getQueryString();
|
||||
//TODO is this safe if the client is sending several requests concurrently in the same session to secured resources?
|
||||
session.setAttribute(__J_URI, request.getScheme() + "://"
|
||||
+ request.getServerName()
|
||||
+ ":"
|
||||
+ request.getServerPort()
|
||||
+ URIUtil.addPaths(request.getContextPath(), uri));
|
||||
|
||||
synchronized (session)
|
||||
{
|
||||
if (session.getAttribute(__J_URI)==null)
|
||||
session.setAttribute(__J_URI, request.getScheme() + "://"
|
||||
+ request.getServerName()
|
||||
+ ":"
|
||||
+ request.getServerPort()
|
||||
+ URIUtil.addPaths(request.getContextPath(), uri));
|
||||
}
|
||||
|
||||
if (_dispatch)
|
||||
{
|
||||
RequestDispatcher dispatcher = request.getRequestDispatcher(_formLoginPage);
|
||||
|
@ -234,8 +243,8 @@ public class FormAuthenticator extends LoginAuthenticator
|
|||
{
|
||||
response.sendRedirect(URIUtil.addPaths(request.getContextPath(),_formLoginPage));
|
||||
}
|
||||
return Authentication.CHALLENGE;
|
||||
|
||||
return DefaultAuthentication.SEND_CONTINUE_RESULTS;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -254,9 +263,9 @@ public class FormAuthenticator extends LoginAuthenticator
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Authentication.Status secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
public boolean secureResponse(ServletRequest req, ServletResponse res, boolean mandatory, Authentication validatedUser) throws ServerAuthException
|
||||
{
|
||||
return Authentication.Status.SUCCESS;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.security.Principal;
|
|||
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import org.eclipse.jetty.security.IdentityService;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
|
||||
/**
|
||||
|
@ -38,7 +39,7 @@ public class LoginCallbackImpl implements LoginCallback
|
|||
|
||||
private Principal userPrincipal;
|
||||
|
||||
private String[] roles = UserIdentity.NO_ROLES;
|
||||
private String[] roles = IdentityService.NO_ROLES;
|
||||
|
||||
//TODO could use Credential instance instead of Object if Basic/Form create a Password object
|
||||
public LoginCallbackImpl (Subject subject, String userName, Object credential)
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.eclipse.jetty.security.Authentication;
|
|||
import org.eclipse.jetty.security.Authenticator;
|
||||
import org.eclipse.jetty.security.DefaultAuthentication;
|
||||
import org.eclipse.jetty.security.ServerAuthException;
|
||||
import org.eclipse.jetty.security.Authentication.Status;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
|
||||
/**
|
||||
|
@ -46,26 +45,27 @@ public class SessionCachingAuthenticator extends DelegateAuthenticator
|
|||
HttpSession session = ((HttpServletRequest)request).getSession(mandatory);
|
||||
// not mandatory and not authenticated
|
||||
if (session == null)
|
||||
return DefaultAuthentication.SUCCESS_UNAUTH_RESULTS;
|
||||
return Authentication.NOT_CHECKED;
|
||||
|
||||
Authentication authentication = (Authentication) session.getAttribute(__J_AUTHENTICATED);
|
||||
if (authentication != null)
|
||||
return authentication;
|
||||
|
||||
authentication = _delegate.validateRequest(request, response, mandatory);
|
||||
if (authentication != null && authentication.getUserIdentity().getSubject() != null)
|
||||
if (authentication!=null && authentication.isSuccess())
|
||||
{
|
||||
Authentication next=new FormAuthentication(Authentication.Status.SUCCESS,_delegate,authentication.getUserIdentity());
|
||||
session.setAttribute(__J_AUTHENTICATED, next);
|
||||
Authentication cached=new FormAuthentication(_delegate,authentication.getUserIdentity());
|
||||
session.setAttribute(__J_AUTHENTICATED, cached);
|
||||
}
|
||||
|
||||
return authentication;
|
||||
}
|
||||
|
||||
protected class FormAuthentication extends DefaultAuthentication implements HttpSessionAttributeListener
|
||||
{
|
||||
public FormAuthentication(Status authStatus, Authenticator authenticator, UserIdentity userIdentity)
|
||||
public FormAuthentication(Authenticator authenticator, UserIdentity userIdentity)
|
||||
{
|
||||
super(authStatus,authenticator,userIdentity);
|
||||
super(authenticator,userIdentity);
|
||||
}
|
||||
|
||||
public void attributeAdded(HttpSessionBindingEvent event)
|
||||
|
|
|
@ -564,7 +564,7 @@ public class ConstraintTest extends TestCase
|
|||
public void handle(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
UserIdentity old = ((Request) request).getUserIdentity();
|
||||
UserIdentity scoped = _security.getIdentityService().associate(old,
|
||||
UserIdentity scoped = _security.getIdentityService().scope(old,
|
||||
new UserIdentity.Scope()
|
||||
{
|
||||
|
||||
|
@ -585,11 +585,6 @@ public class ConstraintTest extends TestCase
|
|||
return map;
|
||||
}
|
||||
|
||||
public String getRunAsRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
});
|
||||
((Request)request).setUserIdentity(scoped);
|
||||
|
||||
|
@ -599,7 +594,7 @@ public class ConstraintTest extends TestCase
|
|||
}
|
||||
finally
|
||||
{
|
||||
_security.getIdentityService().disassociate(scoped);
|
||||
_security.getIdentityService().descope(scoped);
|
||||
((Request)request).setUserIdentity(old);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
private static ShutdownHookThread hookThread = new ShutdownHookThread();
|
||||
private static String _version = (Server.class.getPackage()!=null && Server.class.getPackage().getImplementationVersion()!=null)
|
||||
?Server.class.getPackage().getImplementationVersion()
|
||||
:"7.0.x";
|
||||
:"7.0.0.M1-SNAPSHOT";
|
||||
|
||||
private ThreadPool _threadPool;
|
||||
private Connector[] _connectors;
|
||||
|
|
|
@ -29,8 +29,6 @@ import javax.servlet.ServletResponse;
|
|||
*/
|
||||
public interface UserIdentity
|
||||
{
|
||||
final static String[] NO_ROLES = new String[]{};
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The user subject
|
||||
|
@ -43,12 +41,6 @@ public interface UserIdentity
|
|||
*/
|
||||
Principal getUserPrincipal();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The users roles
|
||||
*/
|
||||
String[] getRoles();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Check if the user is in a role.
|
||||
* This call is used to satisfy authorization calls from
|
||||
|
@ -83,12 +75,6 @@ public interface UserIdentity
|
|||
*/
|
||||
String getName();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The name of a runAs entity. Typically this is a runAs role applied to a servlet.
|
||||
*/
|
||||
String getRunAsRole();
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return A map of role reference names that converts from names used by application code
|
||||
|
@ -119,11 +105,6 @@ public interface UserIdentity
|
|||
return null;
|
||||
}
|
||||
|
||||
public String[] getRoles()
|
||||
{
|
||||
return NO_ROLES;
|
||||
}
|
||||
|
||||
public boolean isUserInRole(String role)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -98,4 +98,21 @@ public abstract class AbstractHandler extends AbstractLifeCycle implements Handl
|
|||
_server.getContainer().removeBean(this);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String dump()
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
dump(b,"");
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void dump(StringBuilder b,String indent)
|
||||
{
|
||||
b.append(toString());
|
||||
b.append(isStarted()?" started":" STOPPED");
|
||||
b.append('\n');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ import org.eclipse.jetty.util.LazyList;
|
|||
/* ------------------------------------------------------------ */
|
||||
/** Abstract Handler Container.
|
||||
* This is the base class for handlers that may contain other handlers.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractHandlerContainer extends AbstractHandler implements HandlerContainer
|
||||
|
@ -83,33 +81,28 @@ public abstract class AbstractHandlerContainer extends AbstractHandler implement
|
|||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String dump()
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
dump(b,this,0);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void dump(StringBuilder b,Handler handler,int indent)
|
||||
protected void dump(StringBuilder b,String indent)
|
||||
{
|
||||
for (int i=0;i<indent;i++)
|
||||
b.append("| ");
|
||||
if (handler==null)
|
||||
b.append("NULL");
|
||||
else
|
||||
{
|
||||
b.append(handler.toString());
|
||||
b.append(handler.isStarted()?" started":" STOPPED");
|
||||
b.append('\n');
|
||||
super.dump(b,indent);
|
||||
|
||||
indent++;
|
||||
if (handler instanceof HandlerContainer)
|
||||
for (Handler h : ((HandlerContainer)handler).getHandlers())
|
||||
dump(b,h,indent);
|
||||
Handler[] handlers = getHandlers();
|
||||
if (handlers!=null)
|
||||
{
|
||||
int last=handlers.length-1;
|
||||
for (int h=0;h<=last;h++)
|
||||
{
|
||||
b.append(indent);
|
||||
b.append(" +-");
|
||||
if (handlers[h] instanceof AbstractHandler)
|
||||
((AbstractHandler)handlers[h]).dump(b,indent+((h==last)?" ":" | "));
|
||||
else
|
||||
{
|
||||
b.append(handlers[h]);
|
||||
b.append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,6 @@ public class ContextHandler extends HandlerWrapper implements Attributes, Server
|
|||
private Object _contextListeners;
|
||||
private Object _contextAttributeListeners;
|
||||
private Object _requestListeners;
|
||||
private Object _asyncListeners;
|
||||
private Object _requestAttributeListeners;
|
||||
private Set<String> _managedAttributes;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public class HttpServerTestBase extends TestCase
|
|||
private static final String REQUEST1=REQUEST1_HEADER+REQUEST1_CONTENT.getBytes().length+"\n\n"+REQUEST1_CONTENT;
|
||||
|
||||
/** The expected response. */
|
||||
private static final String RESPONSE1="HTTP/1.1 200 OK\n"+"Connection: close\n"+"Server: Jetty(7.0.x)\n"+"\n"+"Hello world\n";
|
||||
private static final String RESPONSE1="HTTP/1.1 200 OK\n"+"Connection: close\n"+"Server: Jetty("+Server.getVersion()+")\n"+"\n"+"Hello world\n";
|
||||
|
||||
// Break the request up into three pieces, splitting the header.
|
||||
private static final String FRAGMENT1=REQUEST1.substring(0,16);
|
||||
|
@ -95,7 +95,7 @@ public class HttpServerTestBase extends TestCase
|
|||
"HTTP/1.1 200 OK\n"+
|
||||
"Content-Type: text/xml;charset=ISO-8859-1\n"+
|
||||
"Content-Length: "+RESPONSE2_CONTENT.getBytes().length+"\n"+
|
||||
"Server: Jetty(7.0.x)\n"+
|
||||
"Server: Jetty("+Server.getVersion()+")\n"+
|
||||
"\n"+
|
||||
RESPONSE2_CONTENT;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import javax.servlet.UnavailableException;
|
|||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
|
||||
import org.eclipse.jetty.http.HttpContent;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
|
@ -656,21 +657,23 @@ public class DefaultServlet extends HttpServlet implements ResourceFactory
|
|||
}
|
||||
else
|
||||
{
|
||||
// See if a short direct method can be used?
|
||||
// See if a direct methods can be used?
|
||||
if (out instanceof HttpConnection.Output)
|
||||
{
|
||||
if (_cacheControl!=null)
|
||||
if (response instanceof Response)
|
||||
{
|
||||
if (response instanceof Response)
|
||||
if (_cacheControl!=null)
|
||||
((Response)response).getHttpFields().put(HttpHeaders.CACHE_CONTROL_BUFFER,_cacheControl);
|
||||
else
|
||||
response.setHeader(HttpHeaders.CACHE_CONTROL,_cacheControl.toString());
|
||||
((HttpConnection.Output)out).sendContent(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeHeaders(response,content,content_length);
|
||||
((HttpConnection.Output)out).sendContent(content.getBuffer());
|
||||
}
|
||||
((HttpConnection.Output)out).sendContent(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Write content normally
|
||||
writeHeaders(response,content,content_length);
|
||||
resource.writeTo(out,0,content_length);
|
||||
|
|
|
@ -274,7 +274,11 @@ public class FilterMapping
|
|||
/* ------------------------------------------------------------ */
|
||||
public String toString()
|
||||
{
|
||||
return "(F="+_filterName+","+(_pathSpecs==null?"[]":Arrays.asList(_pathSpecs).toString())+","+(_servletNames==null?"[]":Arrays.asList(_servletNames).toString())+","+_dispatches+")";
|
||||
return
|
||||
(_pathSpecs==null?"[]":Arrays.asList(_pathSpecs).toString())+"/"+
|
||||
(_servletNames==null?"[]":Arrays.asList(_servletNames).toString())+"=="+
|
||||
_dispatches+"=>"+
|
||||
_filterName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -42,6 +43,8 @@ import org.eclipse.jetty.security.IdentityService;
|
|||
import org.eclipse.jetty.security.SecurityHandler;
|
||||
import org.eclipse.jetty.server.Dispatcher;
|
||||
import org.eclipse.jetty.server.DispatcherType;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.HandlerContainer;
|
||||
import org.eclipse.jetty.server.HttpConnection;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.RetryRequest;
|
||||
|
@ -383,7 +386,7 @@ public class ServletHandler extends AbstractHandler
|
|||
if (_identityService!=null)
|
||||
{
|
||||
old_identity=base_request.getUserIdentity();
|
||||
scoped_identity=_identityService.associate(old_identity,servlet_holder);
|
||||
scoped_identity=_identityService.scope(old_identity,servlet_holder);
|
||||
base_request.setUserIdentity(scoped_identity);
|
||||
}
|
||||
|
||||
|
@ -516,7 +519,7 @@ public class ServletHandler extends AbstractHandler
|
|||
|
||||
if (scoped_identity!=null)
|
||||
{
|
||||
_identityService.disassociate(scoped_identity);
|
||||
_identityService.descope(scoped_identity);
|
||||
base_request.setUserIdentity(old_identity);
|
||||
}
|
||||
base_request.setServletName(old_servlet_name);
|
||||
|
@ -1367,4 +1370,50 @@ public class ServletHandler extends AbstractHandler
|
|||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected void dump(StringBuilder b,String indent)
|
||||
{
|
||||
super.dump(b,indent);
|
||||
|
||||
if (getFilterMappings()!=null)
|
||||
{
|
||||
for (FilterMapping f : getFilterMappings())
|
||||
{
|
||||
b.append(indent);
|
||||
b.append(" +-");
|
||||
b.append(f);
|
||||
b.append('\n');
|
||||
}
|
||||
}
|
||||
HashSet<String> servlets = new HashSet<String>();
|
||||
if (getServletMappings()!=null)
|
||||
{
|
||||
for (ServletMapping m : getServletMappings())
|
||||
{
|
||||
servlets.add(m.getServletName());
|
||||
b.append(indent);
|
||||
b.append(" +-");
|
||||
b.append(m);
|
||||
b.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
if (getServlets()!=null)
|
||||
{
|
||||
for (ServletHolder h : getServlets())
|
||||
{
|
||||
if (servlets.contains(h.getName()))
|
||||
continue;
|
||||
b.append(indent);
|
||||
b.append(" +-[]==>");
|
||||
b.append(h.getName());
|
||||
b.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -263,7 +263,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope, Compara
|
|||
try
|
||||
{
|
||||
if (_identityService!=null && _runAsToken!=null)
|
||||
old_run_as=_identityService.associateRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
|
||||
old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
|
||||
|
||||
destroyInstance(_servlet);
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope, Compara
|
|||
finally
|
||||
{
|
||||
if (_identityService!=null && _runAsToken!=null)
|
||||
_identityService.disassociateRunAs(old_run_as);
|
||||
_identityService.unsetRunAs(old_run_as);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,7 +405,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope, Compara
|
|||
// Handle run as
|
||||
if (_identityService!=null && _runAsToken!=null)
|
||||
{
|
||||
old_run_as=_identityService.associateRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
|
||||
old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
|
||||
}
|
||||
|
||||
_servlet.init(_config);
|
||||
|
@ -435,7 +435,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope, Compara
|
|||
{
|
||||
// pop run-as role
|
||||
if (_identityService!=null && _runAsToken!=null)
|
||||
_identityService.disassociateRunAs(old_run_as);
|
||||
_identityService.unsetRunAs(old_run_as);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -512,7 +512,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope, Compara
|
|||
|
||||
// Handle run as
|
||||
if (_identityService!=null && _runAsToken!=null)
|
||||
old_run_as=_identityService.associateRunAs(baseRequest.getUserIdentity(),_runAsToken);
|
||||
old_run_as=_identityService.setRunAs(baseRequest.getUserIdentity(),_runAsToken);
|
||||
|
||||
if (!isAsyncSupported())
|
||||
baseRequest.setAsyncSupported(false);
|
||||
|
@ -531,7 +531,7 @@ public class ServletHolder extends Holder implements UserIdentity.Scope, Compara
|
|||
|
||||
// pop run-as role
|
||||
if (_identityService!=null && _runAsToken!=null)
|
||||
_identityService.disassociateRunAs(old_run_as);
|
||||
_identityService.unsetRunAs(old_run_as);
|
||||
|
||||
// Handle error params.
|
||||
if (servlet_error)
|
||||
|
|
|
@ -75,6 +75,6 @@ public class ServletMapping
|
|||
/* ------------------------------------------------------------ */
|
||||
public String toString()
|
||||
{
|
||||
return "(S="+_servletName+","+(_pathSpecs==null?"[]":Arrays.asList(_pathSpecs).toString())+")";
|
||||
return (_pathSpecs==null?"[]":Arrays.asList(_pathSpecs).toString())+"=>"+_servletName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.eclipse.jetty;
|
|||
import org.eclipse.jetty.http.security.Password;
|
||||
import org.eclipse.jetty.security.HashLoginService;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
public class DemoServer
|
||||
|
@ -13,7 +14,7 @@ public class DemoServer
|
|||
Server server = new Server(8080);
|
||||
|
||||
WebAppContext context = new WebAppContext();
|
||||
context.setWar("./target/jetty-test-webapp-7.0.0.M1-SNAPSHOT"); // TODO YUCK!
|
||||
context.setWar("./target/jetty-test-webapp-"+Server.getVersion()); // TODO YUCK!
|
||||
context.setDefaultsDescriptor("../jetty-webapp/src/main/config/etc/webdefault.xml");
|
||||
server.setHandler(context);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
@ -435,6 +436,15 @@ public class IO
|
|||
return __nullWriter;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return An writer to nowhere
|
||||
*/
|
||||
public static PrintWriter getNullPrintWriter()
|
||||
{
|
||||
return __nullPrintWriter;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
private static class NullWrite extends Writer
|
||||
|
@ -448,7 +458,7 @@ public class IO
|
|||
public void write(String s,int o,int l){}
|
||||
}
|
||||
private static NullWrite __nullWriter = new NullWrite();
|
||||
|
||||
private static PrintWriter __nullPrintWriter = new PrintWriter(__nullWriter);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue