diff options
Diffstat (limited to 'jetty-security/src/main/java/org/eclipse/jetty/security')
20 files changed, 515 insertions, 400 deletions
diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 83a965d652..e444797e60 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -43,7 +43,8 @@ public interface Authenticator /* ------------------------------------------------------------ */ /** * Configure the Authenticator - * @param configuration + * + * @param configuration the configuration */ void setConfiguration(AuthConfiguration configuration); @@ -64,13 +65,16 @@ public interface Authenticator * where the http method of the original request causing authentication * is not the same as the http method resulting from the redirect * after authentication. - * @param request + * + * @param request the request to manipulate */ void prepareRequest(ServletRequest request); /* ------------------------------------------------------------ */ - /** Validate a request + /** + * Validate a request + * * @param request The request * @param response The response * @param mandatory True if authentication is mandatory. @@ -79,18 +83,20 @@ public interface Authenticator * implement {@link org.eclipse.jetty.server.Authentication.ResponseSent}. If Authentication is not manditory, then a * {@link org.eclipse.jetty.server.Authentication.Deferred} may be returned. * - * @throws ServerAuthException + * @throws ServerAuthException if unable to validate request */ Authentication validateRequest(ServletRequest request, ServletResponse response, boolean mandatory) throws ServerAuthException; /* ------------------------------------------------------------ */ /** - * @param request - * @param response - * @param mandatory - * @param validatedUser + * is response secure + * + * @param request the request + * @param response the response + * @param mandatory if security is mandator + * @param validatedUser the user that was validated * @return true if response is secure - * @throws ServerAuthException + * @throws ServerAuthException if unable to test response */ boolean secureResponse(ServletRequest request, ServletResponse response, boolean mandatory, User validatedUser) throws ServerAuthException; @@ -106,7 +112,8 @@ public interface Authenticator String getAuthMethod(); String getRealmName(); - /** Get a SecurityHandler init parameter + /** + * Get a SecurityHandler init parameter * @see SecurityHandler#getInitParameter(String) * @param param parameter name * @return Parameter value or null diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java index bf0e027d57..827e6fbf4c 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java @@ -21,9 +21,6 @@ package org.eclipse.jetty.security; import java.util.List; import java.util.Set; -/** - * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $ - */ public interface ConstraintAware { List<ConstraintMapping> getConstraintMappings(); @@ -32,15 +29,15 @@ public interface ConstraintAware /* ------------------------------------------------------------ */ /** Set Constraint Mappings and roles. * Can only be called during initialization. - * @param constraintMappings - * @param roles + * @param constraintMappings the mappings + * @param roles the roles */ void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles); /* ------------------------------------------------------------ */ /** Add a Constraint Mapping. * May be called for running webapplication as an annotated servlet is instantiated. - * @param mapping + * @param mapping the mapping */ void addConstraintMapping(ConstraintMapping mapping); @@ -48,7 +45,7 @@ public interface ConstraintAware /* ------------------------------------------------------------ */ /** Add a Role definition. * May be called on running webapplication as an annotated servlet is instantiated. - * @param role + * @param role the role */ void addRole(String role); @@ -56,7 +53,7 @@ public interface ConstraintAware * See Servlet Spec 31, sec 13.8.4, pg 145 * When true, requests with http methods not explicitly covered either by inclusion or omissions * in constraints, will have access denied. - * @param deny + * @param deny true for denied method access */ void setDenyUncoveredHttpMethods(boolean deny); @@ -65,6 +62,7 @@ public interface ConstraintAware /** * See Servlet Spec 31, sec 13.8.4, pg 145 * Container must check if there are urls with uncovered http methods + * @return true if urls with uncovered http methods */ boolean checkPathsWithUncoveredHttpMethods(); } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java index 47efd2561a..8708775f22 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java @@ -40,7 +40,6 @@ import javax.servlet.annotation.ServletSecurity.TransportGuarantee; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.PathMap; -import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; @@ -51,14 +50,12 @@ import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.security.Constraint; -/* ------------------------------------------------------------ */ /** * ConstraintSecurityHandler - * + * <p> * Handler to enforce SecurityConstraints. This implementation is servlet spec * 3.1 compliant and pre-computes the constraint combinations for runtime * efficiency. - * */ public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware { @@ -79,9 +76,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr } /* ------------------------------------------------------------ */ - /** - * @param constraint - */ public static Constraint createConstraint(Constraint constraint) { try @@ -98,10 +92,11 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /** * Create a security constraint * - * @param name - * @param authenticate - * @param roles - * @param dataConstraint + * @param name the name of the constraint + * @param authenticate true to authenticate + * @param roles list of roles + * @param dataConstraint the data constraint + * @return the constraint */ public static Constraint createConstraint (String name, boolean authenticate, String[] roles, int dataConstraint) { @@ -117,8 +112,11 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /* ------------------------------------------------------------ */ /** - * @param name - * @param element + * Create a Constraint + * + * @param name the name + * @param element the http constraint element + * @return the created constraint */ public static Constraint createConstraint (String name, HttpConstraintElement element) { @@ -128,10 +126,13 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /* ------------------------------------------------------------ */ /** - * @param name - * @param rolesAllowed - * @param permitOrDeny - * @param transport + * Create Constraint + * + * @param name the name + * @param rolesAllowed the list of allowed roles + * @param permitOrDeny the permission semantic + * @param transport the transport guarantee + * @return the created constraint */ public static Constraint createConstraint (String name, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport) { @@ -168,10 +169,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /* ------------------------------------------------------------ */ - /** - * @param pathSpec - * @param constraintMappings - */ public static List<ConstraintMapping> getConstraintMappingsForPath(String pathSpec, List<ConstraintMapping> constraintMappings) { if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0) @@ -193,8 +190,9 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /** Take out of the constraint mappings those that match the * given path. * - * @param pathSpec + * @param pathSpec the path spec * @param constraintMappings a new list minus the matching constraints + * @return the list of constraint mappings */ public static List<ConstraintMapping> removeConstraintMappingsForPath(String pathSpec, List<ConstraintMapping> constraintMappings) { @@ -216,12 +214,13 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /* ------------------------------------------------------------ */ - /** Generate Constraints and ContraintMappings for the given url pattern and ServletSecurityElement + /** + * Generate Constraints and ContraintMappings for the given url pattern and ServletSecurityElement * - * @param name - * @param pathSpec - * @param securityElement - * @return + * @param name the name + * @param pathSpec the path spec + * @param securityElement the servlet security element + * @return the list of constraint mappings */ public static List<ConstraintMapping> createConstraintsWithMappingsForPath (String name, String pathSpec, ServletSecurityElement securityElement) { @@ -464,7 +463,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr * Create and combine the constraint with the existing processed * constraints. * - * @param mapping + * @param mapping the constraint mapping */ protected void processConstraintMapping(ConstraintMapping mapping) { @@ -522,8 +521,8 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr * the mappings: an entry that names the method of the Request specifically, an * entry that names constraints that apply to all methods, entries of the form * <method>.omission, where the method of the Request is not named in the omission. - * @param mapping - * @param mappings + * @param mapping the constraint mapping + * @param mappings the mappings of roles */ protected void processConstraintMappingWithMethodOmissions (ConstraintMapping mapping, Map<String, RoleInfo> mappings) { @@ -545,8 +544,8 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /* ------------------------------------------------------------ */ /** * Initialize or update the RoleInfo from the constraint - * @param ri - * @param mapping + * @param ri the role info + * @param mapping the constraint mapping */ protected void configureRoleInfo (RoleInfo ri, ConstraintMapping mapping) { @@ -675,7 +674,7 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr if (dataConstraint == null || dataConstraint == UserDataConstraint.None) return true; - HttpConfiguration httpConfig = HttpChannel.getCurrentHttpChannel().getHttpConfiguration(); + HttpConfiguration httpConfig = Request.getBaseRequest(request).getHttpChannel().getHttpConfiguration(); if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral) { @@ -871,9 +870,9 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr * Check if any http method omissions exist in the list of method * to auth info mappings. * - * @param path - * @param methodMappings - * @return + * @param path the path + * @param methodMappings the method mappings + * @return true if ommision exist */ protected boolean omissionsExist (String path, Map<String, RoleInfo> methodMappings) { @@ -891,11 +890,11 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr /* ------------------------------------------------------------ */ /** - * Given a string of the form <method>.<method>.omission + * Given a string of the form <code><method>.<method>.omission</code> * split out the individual method names. * - * @param omission - * @return + * @param omission the method + * @return the list of strings */ protected Set<String> getOmittedMethods (String omission) { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/CrossContextPsuedoSession.java b/jetty-security/src/main/java/org/eclipse/jetty/security/CrossContextPsuedoSession.java deleted file mode 100644 index 9e82addbea..0000000000 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/CrossContextPsuedoSession.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.security; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $ - * @deprecated - */ -public interface CrossContextPsuedoSession<T> -{ - - T fetch(HttpServletRequest request); - - void store(T data, HttpServletResponse response); - - void clear(HttpServletRequest request); - -} diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java deleted file mode 100644 index e205d774d8..0000000000 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java +++ /dev/null @@ -1,100 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.security; - -import java.security.SecureRandom; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * @version $Rev: 4660 $ $Date: 2009-02-25 17:29:53 +0100 (Wed, 25 Feb 2009) $ - * @deprecated - */ -public class HashCrossContextPsuedoSession<T> implements CrossContextPsuedoSession<T> -{ - private final String _cookieName; - - private final String _cookiePath; - - private final Random _random = new SecureRandom(); - - private final Map<String, T> _data = new HashMap<String, T>(); - - public HashCrossContextPsuedoSession(String cookieName, String cookiePath) - { - this._cookieName = cookieName; - this._cookiePath = cookiePath == null ? "/" : cookiePath; - } - - public T fetch(HttpServletRequest request) - { - Cookie[] cookies = request.getCookies(); - if (cookies == null) - return null; - - for (Cookie cookie : cookies) - { - if (_cookieName.equals(cookie.getName())) - { - String key = cookie.getValue(); - return _data.get(key); - } - } - return null; - } - - public void store(T datum, HttpServletResponse response) - { - String key; - - synchronized (_data) - { - // Create new ID - while (true) - { - key = Long.toString(Math.abs(_random.nextLong()), 30 + (int) (System.currentTimeMillis() % 7)); - if (!_data.containsKey(key)) break; - } - - _data.put(key, datum); - } - - Cookie cookie = new Cookie(_cookieName, key); - cookie.setPath(_cookiePath); - response.addCookie(cookie); - } - - public void clear(HttpServletRequest request) - { - for (Cookie cookie : request.getCookies()) - { - if (_cookieName.equals(cookie.getName())) - { - String key = cookie.getValue(); - _data.remove(key); - break; - } - } - } -} diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java index beb051b621..d49f158946 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java @@ -19,7 +19,11 @@ package org.eclipse.jetty.security; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import org.eclipse.jetty.security.MappedLoginService.KnownUser; import org.eclipse.jetty.security.PropertyUserStore.UserListener; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.Scanner; @@ -31,18 +35,18 @@ import org.eclipse.jetty.util.security.Credential; /* ------------------------------------------------------------ */ /** * Properties User Realm. - * + * <p> * An implementation of UserRealm that stores users and roles in-memory in HashMaps. - * <P> + * <p> * Typically these maps are populated by calling the load() method or passing a properties resource to the constructor. The format of the properties file is: * - * <PRE> + * <pre> * username: password [,rolename ...] - * </PRE> + * </pre> * * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password * checksums. - * + * <p> * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:. */ public class HashLoginService extends MappedLoginService implements UserListener @@ -52,7 +56,29 @@ public class HashLoginService extends MappedLoginService implements UserListener private PropertyUserStore _propertyUserStore; private String _config; private Resource _configResource; - private int _refreshInterval = 0;// default is not to reload + private boolean hotReload = false; // default is not to reload + + + + public class HashKnownUser extends KnownUser + { + String[] _roles; + + public HashKnownUser(String name, Credential credential) + { + super(name, credential); + } + + public void setRoles (String[] roles) + { + _roles = roles; + } + + public String[] getRoles() + { + return _roles; + } + } /* ------------------------------------------------------------ */ public HashLoginService() @@ -101,17 +127,51 @@ public class HashLoginService extends MappedLoginService implements UserListener { _config = config; } + + /** + * Is hot reload enabled on this user store + * + * @return true if hot reload was enabled before startup + */ + public boolean isHotReload() + { + return hotReload; + } + + /** + * Enable Hot Reload of the Property File + * + * @param enable true to enable, false to disable + */ + public void setHotReload(boolean enable) + { + if (isRunning()) + { + throw new IllegalStateException("Cannot set hot reload while user store is running"); + } + this.hotReload = enable; + } /* ------------------------------------------------------------ */ - public void setRefreshInterval(int msec) + /** + * sets the refresh interval (in seconds) + * @param sec the refresh interval + * @deprecated use {@link #setHotReload(boolean)} instead + */ + @Deprecated + public void setRefreshInterval(int sec) { - _refreshInterval = msec; } /* ------------------------------------------------------------ */ + /** + * @return refresh interval in seconds for how often the properties file should be checked for changes + * @deprecated use {@link #isHotReload()} instead + */ + @Deprecated public int getRefreshInterval() { - return _refreshInterval; + return (hotReload)?1:0; } /* ------------------------------------------------------------ */ @@ -128,6 +188,41 @@ public class HashLoginService extends MappedLoginService implements UserListener // TODO: Consider refactoring MappedLoginService to not have to override with unused methods } + + + @Override + protected String[] loadRoleInfo(KnownUser user) + { + UserIdentity id = _propertyUserStore.getUserIdentity(user.getName()); + if (id == null) + return null; + + + Set<RolePrincipal> roles = id.getSubject().getPrincipals(RolePrincipal.class); + if (roles == null) + return null; + + List<String> list = new ArrayList<>(); + for (RolePrincipal r:roles) + list.add(r.getName()); + + return list.toArray(new String[roles.size()]); + } + + @Override + protected KnownUser loadUserInfo(String userName) + { + UserIdentity id = _propertyUserStore.getUserIdentity(userName); + if (id != null) + { + return (KnownUser)id.getUserPrincipal(); + } + + return null; + } + + + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() @@ -140,11 +235,11 @@ public class HashLoginService extends MappedLoginService implements UserListener if (_propertyUserStore == null) { if(LOG.isDebugEnabled()) - LOG.debug("doStart: Starting new PropertyUserStore. PropertiesFile: " + _config + " refreshInterval: " + _refreshInterval); + LOG.debug("doStart: Starting new PropertyUserStore. PropertiesFile: " + _config + " hotReload: " + hotReload); _propertyUserStore = new PropertyUserStore(); - _propertyUserStore.setRefreshInterval(_refreshInterval); - _propertyUserStore.setConfig(_config); + _propertyUserStore.setHotReload(hotReload); + _propertyUserStore.setConfigPath(_config); _propertyUserStore.registerUserListener(this); _propertyUserStore.start(); } @@ -169,9 +264,11 @@ public class HashLoginService extends MappedLoginService implements UserListener { if (LOG.isDebugEnabled()) LOG.debug("update: " + userName + " Roles: " + roleArray.length); - putUser(userName,credential,roleArray); + //TODO need to remove and replace the authenticated user? } + + /* ------------------------------------------------------------ */ @Override public void remove(String userName) diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index b37cc5ccc6..c04bee8e49 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -24,10 +24,8 @@ import javax.security.auth.Subject; import org.eclipse.jetty.server.UserIdentity; -/* ------------------------------------------------------------ */ /** * Associates UserIdentities from with threads and UserIdentity.Contexts. - * */ public interface IdentityService { @@ -37,7 +35,7 @@ public interface IdentityService /** * Associate a user identity with the current thread. * This is called with as a thread enters the - * {@link SecurityHandler#handle(String, Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} + * {@link SecurityHandler#handle(String, org.eclipse.jetty.server.Request, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} * method and then again with a null argument as that call exits. * @param user The current user or null for no user to associated. * @return an object representing the previous associated state diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java index 98f7664a88..dddac27b08 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java @@ -29,6 +29,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; +import javax.servlet.ServletRequest; + import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.log.Log; @@ -39,24 +41,17 @@ import org.eclipse.jetty.util.security.Credential; /* ------------------------------------------------------------ */ /** * HashMapped User Realm with JDBC as data source. - * The login() method checks the inherited Map for the user. If the user is not + * The {@link #login(String, Object, ServletRequest)} method checks the inherited Map for the user. If the user is not * found, it will fetch details from the database and populate the inherited - * Map. It then calls the superclass login() method to perform the actual + * Map. It then calls the superclass {@link #login(String, Object, ServletRequest)} method to perform the actual * authentication. Periodically (controlled by configuration parameter), * internal hashes are cleared. Caching can be disabled by setting cache refresh * interval to zero. Uses one database connection that is initialized at - * startup. Reconnect on failures. authenticate() is 'synchronized'. - * + * startup. Reconnect on failures. + * <p> * An example properties file for configuration is in - * $JETTY_HOME/etc/jdbcRealm.properties - * - * @version $Id: JDBCLoginService.java 4792 2009-03-18 21:55:52Z gregw $ - * - * - * - * + * <code>${jetty.home}/etc/jdbcRealm.properties</code> */ - public class JDBCLoginService extends MappedLoginService { private static final Logger LOG = Log.getLogger(JDBCLoginService.class); @@ -75,6 +70,26 @@ public class JDBCLoginService extends MappedLoginService protected String _userSql; protected String _roleSql; + + /** + * JDBCKnownUser + */ + public class JDBCKnownUser extends KnownUser + { + int _userKey; + + public JDBCKnownUser(String name, Credential credential, int key) + { + super(name, credential); + _userKey = key; + } + + + public int getUserKey () + { + return _userKey; + } + } /* ------------------------------------------------------------ */ public JDBCLoginService() @@ -209,7 +224,7 @@ public class JDBCLoginService extends MappedLoginService /* ------------------------------------------------------------ */ @Override - public UserIdentity login(String username, Object credentials) + public UserIdentity login(String username, Object credentials, ServletRequest request) { long now = System.currentTimeMillis(); if (now - _lastHashPurge > _cacheTime || _cacheTime == 0) @@ -219,7 +234,7 @@ public class JDBCLoginService extends MappedLoginService closeConnection(); } - return super.login(username,credentials); + return super.login(username,credentials, request); } /* ------------------------------------------------------------ */ @@ -229,7 +244,7 @@ public class JDBCLoginService extends MappedLoginService } /* ------------------------------------------------------------ */ - @Override + @Deprecated protected UserIdentity loadUser(String username) { try @@ -249,6 +264,8 @@ public class JDBCLoginService extends MappedLoginService { int key = rs1.getInt(_userTableKey); String credentials = rs1.getString(_userTablePasswordField); + + List<String> roles = new ArrayList<String>(); try (PreparedStatement stat2 = _con.prepareStatement(_roleSql)) @@ -260,7 +277,7 @@ public class JDBCLoginService extends MappedLoginService roles.add(rs2.getString(_roleTableRoleField)); } } - return putUser(username, credentials, roles.toArray(new String[roles.size()])); + return putUser(username, Credential.getCredential(credentials), roles.toArray(new String[roles.size()])); } } } @@ -272,11 +289,83 @@ public class JDBCLoginService extends MappedLoginService } return null; } + + + /** + * @see org.eclipse.jetty.security.MappedLoginService#loadUserInfo(java.lang.String) + */ + public KnownUser loadUserInfo (String username) + { + try + { + if (null == _con) + connectDatabase(); + + if (null == _con) + throw new SQLException("Can't connect to database"); + + try (PreparedStatement stat1 = _con.prepareStatement(_userSql)) + { + stat1.setObject(1, username); + try (ResultSet rs1 = stat1.executeQuery()) + { + if (rs1.next()) + { + int key = rs1.getInt(_userTableKey); + String credentials = rs1.getString(_userTablePasswordField); + + return new JDBCKnownUser (username, Credential.getCredential(credentials), key); + } + } + } + } + catch (SQLException e) + { + LOG.warn("UserRealm " + getName() + " could not load user information from database", e); + closeConnection(); + } + + return null; + } + - /* ------------------------------------------------------------ */ - protected UserIdentity putUser (String username, String credentials, String[] roles) + + /** + * @see org.eclipse.jetty.security.MappedLoginService#loadRoleInfo(org.eclipse.jetty.security.MappedLoginService.KnownUser) + */ + public String[] loadRoleInfo (KnownUser user) { - return putUser(username, Credential.getCredential(credentials),roles); + JDBCKnownUser jdbcUser = (JDBCKnownUser)user; + + try + { + if (null == _con) + connectDatabase(); + + if (null == _con) + throw new SQLException("Can't connect to database"); + + + List<String> roles = new ArrayList<String>(); + + try (PreparedStatement stat2 = _con.prepareStatement(_roleSql)) + { + stat2.setInt(1, jdbcUser.getUserKey()); + try (ResultSet rs2 = stat2.executeQuery()) + { + while (rs2.next()) + roles.add(rs2.getString(_roleTableRoleField)); + return roles.toArray(new String[roles.size()]); + } + } + } + catch (SQLException e) + { + LOG.warn("UserRealm " + getName() + " could not load user information from database", e); + closeConnection(); + } + + return null; } @@ -292,5 +381,4 @@ public class JDBCLoginService extends MappedLoginService } _con = null; } - } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java index b1d9aa437c..8917c6e062 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java @@ -18,6 +18,8 @@ package org.eclipse.jetty.security; +import javax.servlet.ServletRequest; + import org.eclipse.jetty.server.UserIdentity; @@ -42,14 +44,15 @@ public interface LoginService /** Login a user. * @param username The user name * @param credentials The users credentials + * @param request TODO * @return A UserIdentity if the credentials matched, otherwise null */ - UserIdentity login(String username,Object credentials); + UserIdentity login(String username,Object credentials, ServletRequest request); /* ------------------------------------------------------------ */ /** Validate a user identity. * Validate that a UserIdentity previously created by a call - * to {@link #login(String, Object)} is still valid. + * to {@link #login(String, Object, ServletRequest)} is still valid. * @param user The user to validate * @return true if authentication has not been revoked for the user. */ diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java index 4cec9b375d..629b7f5535 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java @@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.security.auth.Subject; +import javax.servlet.ServletRequest; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.component.AbstractLifeCycle; @@ -138,6 +139,8 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo public void logout(UserIdentity identity) { LOG.debug("logout {}",identity); + + //TODO should remove the user????? } /* ------------------------------------------------------------ */ @@ -199,6 +202,24 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo _users.put(userName,identity); return identity; } + + + + + public synchronized UserIdentity putUser (KnownUser userPrincipal, String[] roles) + { + Subject subject = new Subject(); + subject.getPrincipals().add(userPrincipal); + subject.getPrivateCredentials().add(userPrincipal._credential); + if (roles!=null) + for (String role : roles) + subject.getPrincipals().add(new RolePrincipal(role)); + subject.setReadOnly(); + UserIdentity identity=_identityService.newUserIdentity(subject,userPrincipal,roles); + _users.put(userPrincipal._name,identity); + return identity; + } + /* ------------------------------------------------------------ */ public void removeUser(String username) @@ -208,9 +229,9 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo /* ------------------------------------------------------------ */ /** - * @see org.eclipse.jetty.security.LoginService#login(java.lang.String, java.lang.Object) + * @see org.eclipse.jetty.security.LoginService#login(java.lang.String, java.lang.Object, ServletRequest) */ - public UserIdentity login(String username, Object credentials) + public UserIdentity login(String username, Object credentials, ServletRequest request) { if (username == null) return null; @@ -218,9 +239,17 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo UserIdentity user = _users.get(username); if (user==null) - user = loadUser(username); - - if (user!=null) + { + KnownUser userPrincipal = loadUserInfo(username); + if (userPrincipal.authenticate(credentials)) + { + //safe to load the roles + String[] roles = loadRoleInfo(userPrincipal); + user = putUser(userPrincipal, roles); + return user; + } + } + else { UserPrincipal principal = (UserPrincipal)user.getUserPrincipal(); if (principal.authenticate(credentials)) @@ -240,7 +269,10 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo return false; } - + /* ------------------------------------------------------------ */ + protected abstract String[] loadRoleInfo (KnownUser user); + /* ------------------------------------------------------------ */ + protected abstract KnownUser loadUserInfo (String username); /* ------------------------------------------------------------ */ protected abstract UserIdentity loadUser(String username); diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java index cbd3bfdd74..51dd0f1d5e 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -19,8 +19,8 @@ package org.eclipse.jetty.security; import java.io.File; -import java.io.FilenameFilter; import java.io.IOException; +import java.nio.file.Path; import java.security.Principal; import java.util.ArrayList; import java.util.HashMap; @@ -36,37 +36,39 @@ import javax.security.auth.Subject; import org.eclipse.jetty.security.MappedLoginService.KnownUser; import org.eclipse.jetty.security.MappedLoginService.RolePrincipal; import org.eclipse.jetty.server.UserIdentity; -import org.eclipse.jetty.util.Scanner; -import org.eclipse.jetty.util.Scanner.BulkListener; +import org.eclipse.jetty.util.PathWatcher; +import org.eclipse.jetty.util.PathWatcher.PathWatchEvent; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.PathResource; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.security.Credential; /** * PropertyUserStore - * + * <p> * This class monitors a property file of the format mentioned below and notifies registered listeners of the changes to the the given file. * - * <PRE> + * <pre> * username: password [,rolename ...] - * </PRE> + * </pre> * * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password * checksums. * * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:. */ -public class PropertyUserStore extends AbstractLifeCycle +public class PropertyUserStore extends AbstractLifeCycle implements PathWatcher.Listener { private static final Logger LOG = Log.getLogger(PropertyUserStore.class); - private String _config; + private Path _configPath; private Resource _configResource; - private Scanner _scanner; - private int _refreshInterval = 0;// default is not to reload + + private PathWatcher pathWatcher; + private boolean hotReload = false; // default is not to reload private IdentityService _identityService = new DefaultIdentityService(); private boolean _firstLoad = true; // true if first load, false from that point on @@ -74,67 +76,165 @@ public class PropertyUserStore extends AbstractLifeCycle private final Map<String, UserIdentity> _knownUserIdentities = new HashMap<String, UserIdentity>(); private List<UserListener> _listeners; - /* ------------------------------------------------------------ */ + /** + * Get the config (as a string) + * @return the config path as a string + * @deprecated use {@link #getConfigPath()} instead + */ + @Deprecated public String getConfig() { - return _config; + return _configPath.toString(); } - /* ------------------------------------------------------------ */ - public void setConfig(String config) + /** + * Set the Config Path from a String reference to a file + * @param configFile the config file + * @deprecated use {@link #setConfigPath(String)} instead + */ + @Deprecated + public void setConfig(String configFile) { - _config = config; + setConfigPath(configFile); + } + + /** + * Get the Config {@link Path} reference. + * @return the config path + */ + public Path getConfigPath() + { + return _configPath; } - /* ------------------------------------------------------------ */ - public UserIdentity getUserIdentity(String userName) + /** + * Set the Config Path from a String reference to a file + * @param configFile the config file + */ + public void setConfigPath(String configFile) + { + if (configFile == null) { - return _knownUserIdentities.get(userName); + _configPath = null; } + else + { + _configPath = new File(configFile).toPath(); + } + } + + /** + * Set the Config Path from a {@link File} reference + * @param configFile the config file + */ + public void setConfigPath(File configFile) + { + _configPath = configFile.toPath(); + } + + /** + * Set the Config Path + * @param configPath the config path + */ + public void setConfigPath(Path configPath) + { + _configPath = configPath; + } + + /* ------------------------------------------------------------ */ + public UserIdentity getUserIdentity(String userName) + { + return _knownUserIdentities.get(userName); + } /* ------------------------------------------------------------ */ /** - * returns the resource associated with the configured properties file, creating it if necessary + * @return the resource associated with the configured properties file, creating it if necessary + * @throws IOException if unable to get the resource */ public Resource getConfigResource() throws IOException { if (_configResource == null) { - _configResource = Resource.newResource(_config); + _configResource = new PathResource(_configPath); } return _configResource; } + + /** + * Is hot reload enabled on this user store + * + * @return true if hot reload was enabled before startup + */ + public boolean isHotReload() + { + return hotReload; + } + + /** + * Enable Hot Reload of the Property File + * + * @param enable true to enable, false to disable + */ + public void setHotReload(boolean enable) + { + if (isRunning()) + { + throw new IllegalStateException("Cannot set hot reload while user store is running"); + } + this.hotReload = enable; + } /* ------------------------------------------------------------ */ /** * sets the refresh interval (in seconds) + * @param sec the refresh interval + * @deprecated use {@link #setHotReload(boolean)} instead */ - public void setRefreshInterval(int msec) + @Deprecated + public void setRefreshInterval(int sec) { - _refreshInterval = msec; } /* ------------------------------------------------------------ */ /** - * refresh interval in seconds for how often the properties file should be checked for changes + * @return refresh interval in seconds for how often the properties file should be checked for changes + * @deprecated use {@link #isHotReload()} instead */ + @Deprecated public int getRefreshInterval() { - return _refreshInterval; + return (hotReload)?1:0; + } + + @Override + public String toString() + { + StringBuilder s = new StringBuilder(); + s.append(this.getClass().getName()); + s.append("["); + s.append("users.count=").append(this._knownUsers.size()); + s.append("identityService=").append(this._identityService); + s.append("]"); + return s.toString(); } /* ------------------------------------------------------------ */ private void loadUsers() throws IOException { - if (_config == null) + if (_configPath == null) return; if (LOG.isDebugEnabled()) - LOG.debug("Load " + this + " from " + _config); + { + LOG.debug("Loading " + this + " from " + _configPath); + } + Properties properties = new Properties(); if (getConfigResource().exists()) properties.load(getConfigResource().getInputStream()); + Set<String> known = new HashSet<String>(); for (Map.Entry<Object, Object> entry : properties.entrySet()) @@ -211,8 +311,13 @@ public class PropertyUserStore extends AbstractLifeCycle * set initial load to false as there should be no more initial loads */ _firstLoad = false; + + if (LOG.isDebugEnabled()) + { + LOG.debug("Loaded " + this + " from " + _configPath); + } } - + /* ------------------------------------------------------------ */ /** * Depending on the value of the refresh interval, this method will either start up a scanner thread that will monitor the properties file for changes after @@ -225,66 +330,29 @@ public class PropertyUserStore extends AbstractLifeCycle { super.doStart(); - if (getRefreshInterval() > 0) + loadUsers(); + if ( isHotReload() && (_configPath != null) ) { - _scanner = new Scanner(); - _scanner.setScanInterval(getRefreshInterval()); - List<File> dirList = new ArrayList<File>(1); - dirList.add(getConfigResource().getFile().getParentFile()); - _scanner.setScanDirs(dirList); - _scanner.setFilenameFilter(new FilenameFilter() - { - public boolean accept(File dir, String name) - { - File f = new File(dir,name); - try - { - if (f.compareTo(getConfigResource().getFile()) == 0) - { - return true; - } - } - catch (IOException e) - { - return false; - } - - return false; - } - - }); - - _scanner.addListener(new BulkListener() - { - public void filesChanged(List<String> filenames) throws Exception - { - if (filenames == null) - return; - if (filenames.isEmpty()) - return; - if (filenames.size() == 1) - { - Resource r = Resource.newResource(filenames.get(0)); - if (r.getFile().equals(_configResource.getFile())) - loadUsers(); - } - } - - public String toString() - { - return "PropertyUserStore$Scanner"; - } - - }); - - _scanner.setReportExistingFilesOnStartup(true); - _scanner.setRecursive(false); - _scanner.start(); + this.pathWatcher = new PathWatcher(); + this.pathWatcher.watch(_configPath); + this.pathWatcher.addListener(this); + this.pathWatcher.setNotifyExistingOnStart(false); + this.pathWatcher.start(); } - else + + } + + @Override + public void onPathWatchEvent(PathWatchEvent event) + { + try { loadUsers(); } + catch (IOException e) + { + LOG.warn(e); + } } /* ------------------------------------------------------------ */ @@ -294,9 +362,9 @@ public class PropertyUserStore extends AbstractLifeCycle protected void doStop() throws Exception { super.doStop(); - if (_scanner != null) - _scanner.stop(); - _scanner = null; + if (this.pathWatcher != null) + this.pathWatcher.stop(); + this.pathWatcher = null; } /** @@ -335,6 +403,7 @@ public class PropertyUserStore extends AbstractLifeCycle /** * registers a listener to be notified of the contents of the property file + * @param listener the user listener */ public void registerUserListener(UserListener listener) { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index bfcb8fa695..88df1018c5 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -29,25 +29,22 @@ import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.server.handler.HandlerWrapper; -import org.eclipse.jetty.server.session.AbstractSession; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; /** * Abstract SecurityHandler. + * <p> * Select and apply an {@link Authenticator} to a request. * <p> * The Authenticator may either be directly set on the handler @@ -58,7 +55,6 @@ import org.eclipse.jetty.util.log.Logger; * Authentication.Configuration. At startup, any context init parameters * that start with "org.eclipse.jetty.security." that do not have * values in the SecurityHandler init parameters, are copied. - * */ public abstract class SecurityHandler extends HandlerWrapper implements Authenticator.AuthConfiguration { @@ -133,8 +129,9 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti } /* ------------------------------------------------------------ */ - /** Set the authenticator. - * @param authenticator + /** + * Set the authenticator. + * @param authenticator the authenticator * @throws IllegalStateException if the SecurityHandler is running */ public void setAuthenticator(Authenticator authenticator) @@ -251,8 +248,8 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti /* ------------------------------------------------------------ */ /** Set an initialization parameter. - * @param key - * @param value + * @param key the init key + * @param value the init value * @return previous value * @throws IllegalStateException if the SecurityHandler is running */ @@ -309,33 +306,6 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti getInitParameter(name)==null) setInitParameter(name,context.getInitParameter(name)); } - - //register a session listener to handle securing sessions when authentication is performed - context.getContextHandler().addEventListener(new HttpSessionListener() - { - @Override - public void sessionDestroyed(HttpSessionEvent se) - { - } - - @Override - public void sessionCreated(HttpSessionEvent se) - { - //if current request is authenticated, then as we have just created the session, mark it as secure, as it has not yet been returned to a user - HttpChannel<?> channel = HttpChannel.getCurrentHttpChannel(); - - if (channel == null) - return; - Request request = channel.getRequest(); - if (request == null) - return; - - if (request.isSecure()) - { - se.getSession().setAttribute(AbstractSession.SESSION_KNOWN_ONLY_TO_AUTHENTICATED, Boolean.TRUE); - } - } - }); } // complicated resolution of login and identity service to handle @@ -445,6 +415,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti /** Set renew the session on Authentication. * <p> * If set to true, then on authentication, the session associated with a reqeuest is invalidated and replaced with a new session. + * @param renew true to renew the authentication on session * @see org.eclipse.jetty.security.Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication() */ public void setSessionRenewedOnAuthentication(boolean renew) diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java index 3155b43ca4..fa610704f6 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.security; import java.util.Properties; import javax.security.auth.Subject; +import javax.servlet.ServletRequest; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.B64Code; @@ -112,7 +113,7 @@ public class SpnegoLoginService extends AbstractLifeCycle implements LoginServic * username will be null since the credentials will contain all the relevant info */ @Override - public UserIdentity login(String username, Object credentials) + public UserIdentity login(String username, Object credentials, ServletRequest request) { String encodedAuthToken = (String)credentials; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java index bfdeb73b4d..1498f73942 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java @@ -36,14 +36,12 @@ import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Authentication.User; import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.util.B64Code; +import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.security.CertificateUtils; import org.eclipse.jetty.util.security.CertificateValidator; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.security.Password; -/** - * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ - */ public class ClientCertAuthenticator extends LoginAuthenticator { /** String name of keystore password property. */ @@ -82,12 +80,6 @@ public class ClientCertAuthenticator extends LoginAuthenticator return Constraint.__CERT_AUTH; } - - - /** - * @return Authentication for request - * @throws ServerAuthException - */ @Override public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException { @@ -106,7 +98,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator if (_validateCerts) { - KeyStore trustStore = getKeyStore(null, + KeyStore trustStore = getKeyStore( _trustStorePath, _trustStoreType, _trustStoreProvider, _trustStorePassword == null ? null :_trustStorePassword.toString()); Collection<? extends CRL> crls = loadCRL(_crlPath); @@ -147,6 +139,11 @@ public class ClientCertAuthenticator extends LoginAuthenticator } } + @Deprecated + protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception + { + return getKeyStore(storePath, storeType, storeProvider, storePassword); + } /* ------------------------------------------------------------ */ /** * Loads keystore using an input stream or a file path in the same @@ -155,17 +152,16 @@ public class ClientCertAuthenticator extends LoginAuthenticator * Required for integrations to be able to override the mechanism * used to load a keystore in order to provide their own implementation. * - * @param storeStream keystore input stream * @param storePath path of keystore file * @param storeType keystore type * @param storeProvider keystore provider * @param storePassword keystore password * @return created keystore - * @throws Exception + * @throws Exception if unable to get keystore */ - protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception + protected KeyStore getKeyStore(String storePath, String storeType, String storeProvider, String storePassword) throws Exception { - return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword); + return CertificateUtils.getKeyStore(Resource.newResource(storePath), storeType, storeProvider, storePassword); } /* ------------------------------------------------------------ */ @@ -178,7 +174,7 @@ public class ClientCertAuthenticator extends LoginAuthenticator * @param crlPath path of certificate revocation list file * @return a (possibly empty) collection view of java.security.cert.CRL objects initialized with the data from the * input stream. - * @throws Exception + * @throws Exception if unable to load CRL */ protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception { diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index 32f04610a9..4b6cae261a 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -140,7 +140,7 @@ public class DeferredAuthentication implements Authentication.Deferred /* ------------------------------------------------------------ */ /** - * @param response + * @param response the response * @return true if this response is from a deferred call to {@link #authenticate(ServletRequest)} */ public static boolean isDeferred(HttpServletResponse response) diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index 99a46a37ca..9359da10a0 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.server.Authentication; diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 6a5b2a617a..85babb76e3 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.Collections; import java.util.Enumeration; import java.util.Locale; + import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -41,7 +42,6 @@ import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.server.Authentication; import org.eclipse.jetty.server.Authentication.User; -import org.eclipse.jetty.server.HttpChannel; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.UserIdentity; @@ -64,8 +64,6 @@ import org.eclipse.jetty.util.security.Constraint; * to the /j_security_check URI within the context. FormAuthentication uses * {@link SessionAuthentication} to wrap Authentication results so that they * are associated with the session.</p> - * - * */ public class FormAuthenticator extends LoginAuthenticator { @@ -109,7 +107,7 @@ public class FormAuthenticator extends LoginAuthenticator * be remembered. If false, only the first uri that leads to a login * page redirect is remembered. * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=379909 - * @param alwaysSave + * @param alwaysSave true to always save the uri */ public void setAlwaysSaveUri (boolean alwaysSave) { @@ -235,9 +233,8 @@ public class FormAuthenticator extends LoginAuthenticator //restore the original request's method on this request if (LOG.isDebugEnabled()) LOG.debug("Restoring original method {} for {} with method {}", method, juri,httpRequest.getMethod()); - Request base_request = HttpChannel.getCurrentHttpChannel().getRequest(); - HttpMethod m = HttpMethod.fromString(method); - base_request.setMethod(m,m.asString()); + Request base_request = Request.getBaseRequest(request); + base_request.setMethod(method); } /* ------------------------------------------------------------ */ @@ -246,6 +243,9 @@ public class FormAuthenticator extends LoginAuthenticator { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; + Request base_request = Request.getBaseRequest(request); + Response base_response = base_request.getResponse(); + String uri = request.getRequestURI(); if (uri==null) uri=URIUtil.SLASH; @@ -290,8 +290,6 @@ public class FormAuthenticator extends LoginAuthenticator LOG.debug("authenticated {}->{}",form_auth,nuri); response.setContentLength(0); - Response base_response = HttpChannel.getCurrentHttpChannel().getResponse(); - Request base_request = HttpChannel.getCurrentHttpChannel().getRequest(); int redirectCode = (base_request.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER); base_response.sendRedirect(redirectCode, response.encodeRedirectURL(nuri)); return form_auth; @@ -317,8 +315,6 @@ public class FormAuthenticator extends LoginAuthenticator else { LOG.debug("auth failed {}->{}",username,_formErrorPage); - Response base_response = HttpChannel.getCurrentHttpChannel().getResponse(); - Request base_request = HttpChannel.getCurrentHttpChannel().getRequest(); int redirectCode = (base_request.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER); base_response.sendRedirect(redirectCode, response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(),_formErrorPage))); } @@ -358,7 +354,6 @@ public class FormAuthenticator extends LoginAuthenticator if (j_post!=null) { LOG.debug("auth rePOST {}->{}",authentication,j_uri); - Request base_request = HttpChannel.getCurrentHttpChannel().getRequest(); base_request.setContentParameters(j_post); } session.removeAttribute(__J_URI); @@ -393,7 +388,6 @@ public class FormAuthenticator extends LoginAuthenticator if (MimeTypes.Type.FORM_ENCODED.is(req.getContentType()) && HttpMethod.POST.is(request.getMethod())) { - Request base_request = (req instanceof Request)?(Request)req:HttpChannel.getCurrentHttpChannel().getRequest(); MultiMap<String> formParameters = new MultiMap<>(); base_request.extractFormParameters(formParameters); session.setAttribute(__J_POST, formParameters); @@ -413,8 +407,6 @@ public class FormAuthenticator extends LoginAuthenticator else { LOG.debug("challenge {}->{}",session.getId(),_formLoginPage); - Response base_response = HttpChannel.getCurrentHttpChannel().getResponse(); - Request base_request = HttpChannel.getCurrentHttpChannel().getRequest(); int redirectCode = (base_request.getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER); base_response.sendRedirect(redirectCode, response.encodeRedirectURL(URIUtil.addPaths(request.getContextPath(),_formLoginPage))); } diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index 4f5a9ec94a..85186951fb 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -58,7 +58,7 @@ public abstract class LoginAuthenticator implements Authenticator /* ------------------------------------------------------------ */ public UserIdentity login(String username, Object password, ServletRequest request) { - UserIdentity user = _loginService.login(username,password); + UserIdentity user = _loginService.login(username,password, request); if (user!=null) { renewSession((HttpServletRequest)request, (request instanceof Request? ((Request)request).getResponse() : null)); @@ -92,11 +92,11 @@ public abstract class LoginAuthenticator implements Authenticator /** Change the session id. * The session is changed to a new instance with a new ID if and only if:<ul> * <li>A session exists. - * <li>The {@link AuthConfiguration#isSessionRenewedOnAuthentication()} returns true. + * <li>The {@link org.eclipse.jetty.security.Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication()} returns true. * <li>The session ID has been given to unauthenticated responses * </ul> - * @param request - * @param response + * @param request the request + * @param response the response * @return The new session. */ protected HttpSession renewSession(HttpServletRequest request, HttpServletResponse response) @@ -109,14 +109,14 @@ public abstract class LoginAuthenticator implements Authenticator { //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users //(indicated by SESSION_SECURED not being set on the session) then we should change id - if (httpSession.getAttribute(AbstractSession.SESSION_KNOWN_ONLY_TO_AUTHENTICATED)!=Boolean.TRUE) + if (httpSession.getAttribute(AbstractSession.SESSION_CREATED_SECURE)!=Boolean.TRUE) { if (httpSession instanceof AbstractSession) { AbstractSession abstractSession = (AbstractSession)httpSession; String oldId = abstractSession.getId(); abstractSession.renewId(request); - abstractSession.setAttribute(AbstractSession.SESSION_KNOWN_ONLY_TO_AUTHENTICATED, Boolean.TRUE); + abstractSession.setAttribute(AbstractSession.SESSION_CREATED_SECURE, Boolean.TRUE); if (abstractSession.isIdChanged() && response != null && (response instanceof Response)) ((Response)response).addCookie(abstractSession.getSessionManager().getSessionCookie(abstractSession, request.getContextPath(), request.isSecure())); LOG.debug("renew {}->{}",oldId,abstractSession.getId()); diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java index 6f589472e4..9155bf3f61 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -71,7 +71,7 @@ public class SessionAuthentication extends AbstractUserAuthentication implements if (login_service==null) throw new IllegalStateException("!LoginService"); - _userIdentity=login_service.login(_name,_credentials); + _userIdentity=login_service.login(_name,_credentials, null); LOG.debug("Deserialized and relogged in {}",this); } @@ -89,7 +89,7 @@ public class SessionAuthentication extends AbstractUserAuthentication implements if (security!=null) security.logout(this); if (_session!=null) - _session.removeAttribute(AbstractSession.SESSION_KNOWN_ONLY_TO_AUTHENTICATED); + _session.removeAttribute(AbstractSession.SESSION_CREATED_SECURE); } @Override diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java index 182635a254..f201606054 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java @@ -46,7 +46,7 @@ public class SpnegoAuthenticator extends LoginAuthenticator /** * Allow for a custom authMethod value to be set for instances where SPENGO may not be appropriate - * @param authMethod + * @param authMethod the auth method */ public SpnegoAuthenticator( String authMethod ) { |