Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-security/src/main/java/org/eclipse/jetty/security')
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java27
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java14
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java77
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/CrossContextPsuedoSession.java37
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/HashCrossContextPsuedoSession.java100
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java123
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java4
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java128
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java7
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/MappedLoginService.java44
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java239
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java43
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoLoginService.java3
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java26
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java2
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java1
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java22
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java12
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java4
-rw-r--r--jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SpnegoAuthenticator.java2
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
* &lt;method&gt;.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 &lt;method&gt;.&lt;method&gt;.omission
+ * Given a string of the form <code>&lt;method&gt;.&lt;method&gt;.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 )
{

Back to the top