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:
Greg Wilkins 2009-04-15 12:39:05 +00:00
parent 5e11796031
commit 3a129bb90f
41 changed files with 591 additions and 285 deletions

View File

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

View File

@ -71,6 +71,7 @@ public class ManyContexts
server.setHandler(contexts);
server.start();
System.err.println(server.dump());
server.join();
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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,13 +130,14 @@ 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)
{
@ -133,17 +145,4 @@ public class JaspiAuthenticator implements Authenticator
}
}
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);
}
}

View File

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

View File

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

View File

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

View File

@ -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;
}
@ -39,11 +37,6 @@ public class DefaultAuthentication implements Authentication
return _authenticator.getAuthMethod();
}
public Authentication.Status getAuthStatus()
{
return _authStatus;
}
public UserIdentity getUserIdentity()
{
return _userIdentity;
@ -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;
}
}
}

View File

@ -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)
{
}
@ -95,11 +95,6 @@ public class DefaultIdentityService implements IdentityService
_roleRefMap=roleRefMap;
}
public String[] getRoles()
{
return _delegate.getRoles();
}
public Subject getSubject()
{
return _delegate.getSubject();

View File

@ -37,11 +37,6 @@ public class DefaultUserIdentity implements UserIdentity
_roles=roles;
}
public String[] getRoles()
{
return _roles;
}
public Subject getSubject()
{
return _subject;

View File

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

View File

@ -26,6 +26,7 @@ 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);
/* ------------------------------------------------------------ */
/**

View File

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

View File

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

View File

@ -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()
{
return _unchecked;
}
public void setUnchecked(boolean unchecked)
public boolean isChecked()
{
this._unchecked = unchecked;
if (unchecked)
return _checked;
}
public void setChecked(boolean checked)
{
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())+"}";
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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,16 +124,19 @@ 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
@ -142,7 +145,8 @@ public class DigestAuthenticator extends LoginAuthenticator
+ "\", algorithm=MD5, qop=\"auth\""
+ (_useStale ? (" stale=" + stale) : ""));
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return DefaultAuthentication.SEND_CONTINUE_RESULTS;
return Authentication.CHALLENGE;
}
catch (IOException e)
{

View File

@ -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,26 +210,27 @@ 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;
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?
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)
{
@ -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;
}
/* ------------------------------------------------------------ */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,8 +23,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
{
@ -85,31 +83,26 @@ public abstract class AbstractHandlerContainer extends AbstractHandler implement
}
/* ------------------------------------------------------------ */
public String dump()
protected void dump(StringBuilder b,String indent)
{
StringBuilder b = new StringBuilder();
dump(b,this,0);
return b.toString();
}
super.dump(b,indent);
/* ------------------------------------------------------------ */
protected void dump(StringBuilder b,Handler handler,int indent)
Handler[] handlers = getHandlers();
if (handlers!=null)
{
for (int i=0;i<indent;i++)
b.append("| ");
if (handler==null)
b.append("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(handler.toString());
b.append(handler.isStarted()?" started":" STOPPED");
b.append('\n');
indent++;
if (handler instanceof HandlerContainer)
for (Handler h : ((HandlerContainer)handler).getHandlers())
dump(b,h,indent);
b.append(handlers[h]);
b.append("\n");
}
}
}
}
}

View File

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

View File

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

View File

@ -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 (_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());
}
}
else
{
// Write content normally
writeHeaders(response,content,content_length);
resource.writeTo(out,0,content_length);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -109,6 +109,7 @@
<module>jetty-client</module>
<module>jetty-xml</module>
<module>jetty-security</module>
<module>jetty-jaspi</module>
<module>jetty-servlet</module>
<module>jetty-webapp</module>
<module>jetty-servlets</module>