1
0
mirror of synced 2026-08-05 17:57:15 +00:00

Reformat code using spring-javaformat

Run `./gradlew format` to reformat all java files.

Issue gh-8945
This commit is contained in:
Phillip Webb
2020-08-10 16:39:17 -05:00
committed by Rob Winch
parent 81d9c6cac5
commit b7fc18262d
2487 changed files with 41506 additions and 46548 deletions
@@ -31,6 +31,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Ben Alex
*/
public interface AuthenticationEntryPoint {
// ~ Methods
// ========================================================================================================
@@ -44,12 +45,12 @@ public interface AuthenticationEntryPoint {
* <p>
* Implementations should modify the headers on the <code>ServletResponse</code> as
* necessary to commence the authentication process.
*
* @param request that resulted in an <code>AuthenticationException</code>
* @param response so that the user agent can begin authentication
* @param authException that caused the invocation
*
*/
void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException;
void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
throws IOException, ServletException;
}
@@ -45,8 +45,7 @@ public class DefaultRedirectStrategy implements RedirectStrategy {
* information (HTTP or HTTPS), so will cause problems if a redirect is being
* performed to change to HTTPS, for example.
*/
public void sendRedirect(HttpServletRequest request, HttpServletResponse response,
String url) throws IOException {
public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException {
String redirectUrl = calculateRedirectUrl(request.getContextPath(), url);
redirectUrl = response.encodeRedirectURL(redirectUrl);
@@ -98,10 +97,11 @@ public class DefaultRedirectStrategy implements RedirectStrategy {
}
/**
* Returns <tt>true</tt>, if the redirection URL should be calculated
* minus the protocol and context path (defaults to <tt>false</tt>).
* Returns <tt>true</tt>, if the redirection URL should be calculated minus the
* protocol and context path (defaults to <tt>false</tt>).
*/
protected boolean isContextRelative() {
return contextRelative;
}
}
@@ -27,12 +27,14 @@ import java.util.*;
* Standard implementation of {@code SecurityFilterChain}.
*
* @author Luke Taylor
*
* @since 3.1
*/
public final class DefaultSecurityFilterChain implements SecurityFilterChain {
private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);
private final RequestMatcher requestMatcher;
private final List<Filter> filters;
public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {
@@ -61,4 +63,5 @@ public final class DefaultSecurityFilterChain implements SecurityFilterChain {
public String toString() {
return "[ " + requestMatcher + ", " + filters + "]";
}
}
@@ -59,9 +59,9 @@ import java.util.*;
* and a list of filters which should be applied to matching requests. Most applications
* will only contain a single filter chain, and if you are using the namespace, you don't
* have to set the chains explicitly. If you require finer-grained control, you can make
* use of the {@code <filter-chain>} namespace element. This defines a URI pattern
* and the list of filters (as comma-separated bean names) which should be applied to
* requests which match the pattern. An example configuration might look like this:
* use of the {@code <filter-chain>} namespace element. This defines a URI pattern and the
* list of filters (as comma-separated bean names) which should be applied to requests
* which match the pattern. An example configuration might look like this:
*
* <pre>
* &lt;bean id="myfilterChainProxy" class="org.springframework.security.web.FilterChainProxy"&gt;
@@ -136,6 +136,7 @@ import java.util.*;
* @author Rob Winch
*/
public class FilterChainProxy extends GenericFilterBean {
// ~ Static fields/initializers
// =====================================================================================
@@ -144,8 +145,7 @@ public class FilterChainProxy extends GenericFilterBean {
// ~ Instance fields
// ================================================================================================
private final static String FILTER_APPLIED = FilterChainProxy.class.getName().concat(
".APPLIED");
private final static String FILTER_APPLIED = FilterChainProxy.class.getName().concat(".APPLIED");
private List<SecurityFilterChain> filterChains;
@@ -175,14 +175,15 @@ public class FilterChainProxy extends GenericFilterBean {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
if (clearContext) {
try {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
doFilterInternal(request, response, chain);
} catch (RequestRejectedException e) {
}
catch (RequestRejectedException e) {
this.requestRejectedHandler.handle((HttpServletRequest) request, (HttpServletResponse) response, e);
}
finally {
@@ -195,21 +196,18 @@ public class FilterChainProxy extends GenericFilterBean {
}
}
private void doFilterInternal(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
FirewalledRequest fwRequest = firewall
.getFirewalledRequest((HttpServletRequest) request);
HttpServletResponse fwResponse = firewall
.getFirewalledResponse((HttpServletResponse) response);
FirewalledRequest fwRequest = firewall.getFirewalledRequest((HttpServletRequest) request);
HttpServletResponse fwResponse = firewall.getFirewalledResponse((HttpServletResponse) response);
List<Filter> filters = getFilters(fwRequest);
if (filters == null || filters.size() == 0) {
if (logger.isDebugEnabled()) {
logger.debug(UrlUtils.buildRequestUrl(fwRequest)
+ (filters == null ? " has no matching filters"
: " has an empty filter list"));
+ (filters == null ? " has no matching filters" : " has an empty filter list"));
}
fwRequest.reset();
@@ -225,7 +223,6 @@ public class FilterChainProxy extends GenericFilterBean {
/**
* Returns the first filter chain matching the supplied URL.
*
* @param request the request to match
* @return an ordered array of Filters defining the filter chain
*/
@@ -241,13 +238,11 @@ public class FilterChainProxy extends GenericFilterBean {
/**
* Convenience method, mainly for testing.
*
* @param url the URL
* @return matching filter list
*/
public List<Filter> getFilters(String url) {
return getFilters(firewall.getFirewalledRequest((new FilterInvocation(url, "GET")
.getRequest())));
return getFilters(firewall.getFirewalledRequest((new FilterInvocation(url, "GET").getRequest())));
}
/**
@@ -261,7 +256,6 @@ public class FilterChainProxy extends GenericFilterBean {
/**
* Used (internally) to specify a validation strategy for the filters in each
* configured chain.
*
* @param filterChainValidator the validator instance which will be invoked on during
* initialization to check the {@code FilterChainProxy} instance.
*/
@@ -273,7 +267,6 @@ public class FilterChainProxy extends GenericFilterBean {
* Sets the "firewall" implementation which will be used to validate and wrap (or
* potentially reject) the incoming requests. The default implementation should be
* satisfactory for most requirements.
*
* @param firewall
*/
public void setFirewall(HttpFirewall firewall) {
@@ -281,7 +274,8 @@ public class FilterChainProxy extends GenericFilterBean {
}
/**
* Sets the {@link RequestRejectedHandler} to be used for requests rejected by the firewall.
* Sets the {@link RequestRejectedHandler} to be used for requests rejected by the
* firewall.
*
* @since 5.2
* @param requestRejectedHandler the {@link RequestRejectedHandler}
@@ -310,14 +304,19 @@ public class FilterChainProxy extends GenericFilterBean {
* the additional internal list of filters which match the request.
*/
private static class VirtualFilterChain implements FilterChain {
private final FilterChain originalChain;
private final List<Filter> additionalFilters;
private final FirewalledRequest firewalledRequest;
private final int size;
private int currentPosition = 0;
private VirtualFilterChain(FirewalledRequest firewalledRequest,
FilterChain chain, List<Filter> additionalFilters) {
private VirtualFilterChain(FirewalledRequest firewalledRequest, FilterChain chain,
List<Filter> additionalFilters) {
this.originalChain = chain;
this.additionalFilters = additionalFilters;
this.size = additionalFilters.size();
@@ -325,8 +324,7 @@ public class FilterChainProxy extends GenericFilterBean {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (currentPosition == size) {
if (logger.isDebugEnabled()) {
logger.debug(UrlUtils.buildRequestUrl(firewalledRequest)
@@ -344,25 +342,29 @@ public class FilterChainProxy extends GenericFilterBean {
Filter nextFilter = additionalFilters.get(currentPosition - 1);
if (logger.isDebugEnabled()) {
logger.debug(UrlUtils.buildRequestUrl(firewalledRequest)
+ " at position " + currentPosition + " of " + size
+ " in additional filter chain; firing Filter: '"
logger.debug(UrlUtils.buildRequestUrl(firewalledRequest) + " at position " + currentPosition
+ " of " + size + " in additional filter chain; firing Filter: '"
+ nextFilter.getClass().getSimpleName() + "'");
}
nextFilter.doFilter(request, response, this);
}
}
}
public interface FilterChainValidator {
void validate(FilterChainProxy filterChainProxy);
}
private static class NullFilterChainValidator implements FilterChainValidator {
@Override
public void validate(FilterChainProxy filterChainProxy) {
}
}
}
@@ -53,6 +53,7 @@ import org.springframework.security.web.util.UrlUtils;
* @author Rob Winch
*/
public class FilterInvocation {
// ~ Static fields
// ==================================================================================================
static final FilterChain DUMMY_CHAIN = (req, res) -> {
@@ -63,14 +64,15 @@ public class FilterInvocation {
// ================================================================================================
private FilterChain chain;
private HttpServletRequest request;
private HttpServletResponse response;
// ~ Constructors
// ===================================================================================================
public FilterInvocation(ServletRequest request, ServletResponse response,
FilterChain chain) {
public FilterInvocation(ServletRequest request, ServletResponse response, FilterChain chain) {
if ((request == null) || (response == null) || (chain == null)) {
throw new IllegalArgumentException("Cannot pass null values to constructor");
}
@@ -88,16 +90,14 @@ public class FilterInvocation {
this(contextPath, servletPath, null, null, method);
}
public FilterInvocation(String contextPath, String servletPath, String pathInfo,
String query, String method) {
public FilterInvocation(String contextPath, String servletPath, String pathInfo, String query, String method) {
DummyRequest request = new DummyRequest();
if (contextPath == null) {
contextPath = "/cp";
}
request.setContextPath(contextPath);
request.setServletPath(servletPath);
request.setRequestURI(
contextPath + servletPath + (pathInfo == null ? "" : pathInfo));
request.setRequestURI(contextPath + servletPath + (pathInfo == null ? "" : pathInfo));
request.setPathInfo(pathInfo);
request.setQueryString(query);
request.setMethod(method);
@@ -116,7 +116,6 @@ public class FilterInvocation {
* <p>
* The returned URL does <b>not</b> reflect the port number determined from a
* {@link org.springframework.security.web.PortResolver}.
*
* @return the full URL of this request
*/
public String getFullRequestUrl() {
@@ -133,7 +132,6 @@ public class FilterInvocation {
/**
* Obtains the web application-specific fragment of the URL.
*
* @return the URL, excluding any server name, context path or servlet path
*/
public String getRequestUrl() {
@@ -152,21 +150,29 @@ public class FilterInvocation {
public String toString() {
return "FilterInvocation: URL: " + getRequestUrl();
}
}
class DummyRequest extends HttpServletRequestWrapper {
private static final HttpServletRequest UNSUPPORTED_REQUEST = (HttpServletRequest) Proxy
.newProxyInstance(DummyRequest.class.getClassLoader(),
new Class[] { HttpServletRequest.class },
new UnsupportedOperationExceptionInvocationHandler());
private static final HttpServletRequest UNSUPPORTED_REQUEST = (HttpServletRequest) Proxy.newProxyInstance(
DummyRequest.class.getClassLoader(), new Class[] { HttpServletRequest.class },
new UnsupportedOperationExceptionInvocationHandler());
private String requestURI;
private String contextPath = "";
private String servletPath;
private String pathInfo;
private String queryString;
private String method;
private final HttpHeaders headers = new HttpHeaders();
private final Map<String, String[]> parameters = new LinkedHashMap<>();
DummyRequest() {
@@ -258,7 +264,7 @@ class DummyRequest extends HttpServletRequestWrapper {
@Override
public int getIntHeader(String name) {
String value = this.headers.getFirst(name);
if (value == null ) {
if (value == null) {
return -1;
}
else {
@@ -294,9 +300,11 @@ class DummyRequest extends HttpServletRequestWrapper {
public void setParameter(String name, String... values) {
this.parameters.put(name, values);
}
}
final class UnsupportedOperationExceptionInvocationHandler implements InvocationHandler {
private static final float JAVA_VERSION = Float.parseFloat(System.getProperty("java.class.version", "52"));
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
@@ -311,14 +319,9 @@ final class UnsupportedOperationExceptionInvocationHandler implements Invocation
return invokeDefaultMethodForJdk8(proxy, method, args);
}
return MethodHandles.lookup()
.findSpecial(
method.getDeclaringClass(),
method.getName(),
MethodType.methodType(method.getReturnType(), new Class[0]),
method.getDeclaringClass()
)
.bindTo(proxy)
.invokeWithArguments(args);
.findSpecial(method.getDeclaringClass(), method.getName(),
MethodType.methodType(method.getReturnType(), new Class[0]), method.getDeclaringClass())
.bindTo(proxy).invokeWithArguments(args);
}
private Object invokeDefaultMethodForJdk8(Object proxy, Method method, Object[] args) throws Throwable {
@@ -326,14 +329,12 @@ final class UnsupportedOperationExceptionInvocationHandler implements Invocation
constructor.setAccessible(true);
Class<?> clazz = method.getDeclaringClass();
return constructor.newInstance(clazz)
.in(clazz)
.unreflectSpecial(method, clazz)
.bindTo(proxy)
return constructor.newInstance(clazz).in(clazz).unreflectSpecial(method, clazz).bindTo(proxy)
.invokeWithArguments(args);
}
private boolean isJdk8OrEarlier() {
return JAVA_VERSION <= 52;
}
}
@@ -23,6 +23,7 @@ package org.springframework.security.web;
* @author Ben Alex
*/
public interface PortMapper {
// ~ Methods
// ========================================================================================================
@@ -31,9 +32,7 @@ public interface PortMapper {
* <P>
* Returns <code>null</code> if unknown.
* </p>
*
* @param httpsPort
*
* @return the HTTP port or <code>null</code> if unknown
*/
Integer lookupHttpPort(Integer httpsPort);
@@ -43,10 +42,9 @@ public interface PortMapper {
* <P>
* Returns <code>null</code> if unknown.
* </p>
*
* @param httpPort
*
* @return the HTTPS port or <code>null</code> if unknown
*/
Integer lookupHttpsPort(Integer httpPort);
}
@@ -32,6 +32,7 @@ import org.springframework.util.Assert;
* @author colin sampaleanu
*/
public class PortMapperImpl implements PortMapper {
// ~ Instance fields
// ================================================================================================
@@ -84,19 +85,16 @@ public class PortMapperImpl implements PortMapper {
* &lt;/map&gt;
* &lt;/property&gt;
* </pre>
*
* @param newMappings A Map consisting of String keys and String values, where for
* each entry the key is the string representation of an integer HTTP port number, and
* the value is the string representation of the corresponding integer HTTPS port
* number.
*
* @throws IllegalArgumentException if input map does not consist of String keys and
* values, each representing an integer port number in the range 1-65535 for that
* mapping.
*/
public void setPortMappings(Map<String, String> newMappings) {
Assert.notNull(newMappings,
"A valid list of HTTPS port mappings must be provided");
Assert.notNull(newMappings, "A valid list of HTTPS port mappings must be provided");
this.httpsPortMappings.clear();
@@ -104,11 +102,9 @@ public class PortMapperImpl implements PortMapper {
Integer httpPort = Integer.valueOf(entry.getKey());
Integer httpsPort = Integer.valueOf(entry.getValue());
if ((httpPort < 1) || (httpPort > 65535)
|| (httpsPort < 1) || (httpsPort > 65535)) {
if ((httpPort < 1) || (httpPort > 65535) || (httpsPort < 1) || (httpsPort > 65535)) {
throw new IllegalArgumentException(
"one or both ports out of legal range: " + httpPort + ", "
+ httpsPort);
"one or both ports out of legal range: " + httpPort + ", " + httpsPort);
}
this.httpsPortMappings.put(httpPort, httpsPort);
@@ -118,4 +114,5 @@ public class PortMapperImpl implements PortMapper {
throw new IllegalArgumentException("must map at least one port");
}
}
}
@@ -30,15 +30,15 @@ import javax.servlet.ServletRequest;
* @author Ben Alex
*/
public interface PortResolver {
// ~ Methods
// ========================================================================================================
/**
* Indicates the port the <code>ServletRequest</code> was received on.
*
* @param request that the method should lookup the port for
*
* @return the port the request was received on
*/
int getServerPort(ServletRequest request);
}
@@ -35,6 +35,7 @@ import javax.servlet.ServletRequest;
* @author Ben Alex
*/
public class PortResolverImpl implements PortResolver {
// ~ Instance fields
// ================================================================================================
@@ -73,4 +74,5 @@ public class PortResolverImpl implements PortResolver {
Assert.notNull(portMapper, "portMapper cannot be null");
this.portMapper = portMapper;
}
}
@@ -35,6 +35,6 @@ public interface RedirectStrategy {
* @param response the response to redirect
* @param url the target URL to redirect to, for example "/login"
*/
void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url)
throws IOException;
void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) throws IOException;
}
@@ -25,9 +25,7 @@ import java.util.*;
* <p>
* Used to configure a {@code FilterChainProxy}.
*
*
* @author Luke Taylor
*
* @since 3.1
*/
public interface SecurityFilterChain {
@@ -35,4 +33,5 @@ public interface SecurityFilterChain {
boolean matches(HttpServletRequest request);
List<Filter> getFilters();
}
@@ -26,6 +26,7 @@ import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
* @since 3.0.3
*/
public final class WebAttributes {
/**
* Used to cache an {@code AccessDeniedException} in the request for rendering.
*
@@ -47,6 +48,7 @@ public final class WebAttributes {
* @see WebInvocationPrivilegeEvaluator
* @since 3.1.3
*/
public static final String WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE = WebAttributes.class
.getName() + ".WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE";
public static final String WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE = WebAttributes.class.getName()
+ ".WEB_INVOCATION_PRIVILEGE_EVALUATOR_ATTRIBUTE";
}
@@ -31,20 +31,19 @@ import javax.servlet.http.HttpServletResponse;
* @author Ben Alex
*/
public interface AccessDeniedHandler {
// ~ Methods
// ========================================================================================================
/**
* Handles an access denied failure.
*
* @param request that resulted in an <code>AccessDeniedException</code>
* @param response so that the user agent can be advised of the failure
* @param accessDeniedException that caused the invocation
*
* @throws IOException in the event of an IOException
* @throws ServletException in the event of a ServletException
*/
void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException,
ServletException;
void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
throws IOException, ServletException;
}
@@ -43,6 +43,7 @@ import org.springframework.security.web.WebAttributes;
* @author Ben Alex
*/
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
// ~ Static fields/initializers
// =====================================================================================
@@ -57,13 +58,11 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
// ========================================================================================================
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException,
ServletException {
AccessDeniedException accessDeniedException) throws IOException, ServletException {
if (!response.isCommitted()) {
if (errorPage != null) {
// Put exception into request scope (perhaps of use to a view)
request.setAttribute(WebAttributes.ACCESS_DENIED_403,
accessDeniedException);
request.setAttribute(WebAttributes.ACCESS_DENIED_403, accessDeniedException);
// Set the 403 status code.
response.setStatus(HttpStatus.FORBIDDEN.value());
@@ -73,8 +72,7 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
dispatcher.forward(request, response);
}
else {
response.sendError(HttpStatus.FORBIDDEN.value(),
HttpStatus.FORBIDDEN.getReasonPhrase());
response.sendError(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase());
}
}
}
@@ -82,9 +80,7 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
/**
* The error page to use. Must begin with a "/" and is interpreted relative to the
* current context root.
*
* @param errorPage the dispatcher path to display
*
* @throws IllegalArgumentException if the argument doesn't comply with the above
* limitations
*/
@@ -95,4 +91,5 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
this.errorPage = errorPage;
}
}
@@ -34,13 +34,12 @@ import org.springframework.util.Assert;
* @author Luke Taylor
* @since 3.0
*/
public class DefaultWebInvocationPrivilegeEvaluator implements
WebInvocationPrivilegeEvaluator {
public class DefaultWebInvocationPrivilegeEvaluator implements WebInvocationPrivilegeEvaluator {
// ~ Static fields/initializers
// =====================================================================================
protected static final Log logger = LogFactory
.getLog(DefaultWebInvocationPrivilegeEvaluator.class);
protected static final Log logger = LogFactory.getLog(DefaultWebInvocationPrivilegeEvaluator.class);
// ~ Instance fields
// ================================================================================================
@@ -50,11 +49,9 @@ public class DefaultWebInvocationPrivilegeEvaluator implements
// ~ Constructors
// ===================================================================================================
public DefaultWebInvocationPrivilegeEvaluator(
AbstractSecurityInterceptor securityInterceptor) {
public DefaultWebInvocationPrivilegeEvaluator(AbstractSecurityInterceptor securityInterceptor) {
Assert.notNull(securityInterceptor, "SecurityInterceptor cannot be null");
Assert.isTrue(
FilterInvocation.class.equals(securityInterceptor.getSecureObjectClass()),
Assert.isTrue(FilterInvocation.class.equals(securityInterceptor.getSecureObjectClass()),
"AbstractSecurityInterceptor does not support FilterInvocations");
Assert.notNull(securityInterceptor.getAccessDecisionManager(),
"AbstractSecurityInterceptor must provide a non-null AccessDecisionManager");
@@ -68,7 +65,6 @@ public class DefaultWebInvocationPrivilegeEvaluator implements
/**
* Determines whether the user represented by the supplied <tt>Authentication</tt>
* object is allowed to invoke the supplied URI.
*
* @param uri the URI excluding the context path (a default context path setting will
* be used)
*/
@@ -85,7 +81,6 @@ public class DefaultWebInvocationPrivilegeEvaluator implements
* metadata applies to a given request URI, so generally the <code>contextPath</code>
* is unimportant unless you are using a custom
* <code>FilterInvocationSecurityMetadataSource</code>.
*
* @param uri the URI excluding the context path
* @param contextPath the context path (may be null, in which case a default value
* will be used).
@@ -94,13 +89,11 @@ public class DefaultWebInvocationPrivilegeEvaluator implements
* be used in evaluation whether access should be granted.
* @return true if access is allowed, false if denied
*/
public boolean isAllowed(String contextPath, String uri, String method,
Authentication authentication) {
public boolean isAllowed(String contextPath, String uri, String method, Authentication authentication) {
Assert.notNull(uri, "uri parameter is required");
FilterInvocation fi = new FilterInvocation(contextPath, uri, method);
Collection<ConfigAttribute> attrs = securityInterceptor
.obtainSecurityMetadataSource().getAttributes(fi);
Collection<ConfigAttribute> attrs = securityInterceptor.obtainSecurityMetadataSource().getAttributes(fi);
if (attrs == null) {
if (securityInterceptor.isRejectPublicInvocations()) {
@@ -115,13 +108,11 @@ public class DefaultWebInvocationPrivilegeEvaluator implements
}
try {
securityInterceptor.getAccessDecisionManager().decide(authentication, fi,
attrs);
securityInterceptor.getAccessDecisionManager().decide(authentication, fi, attrs);
}
catch (AccessDeniedException unauthorized) {
if (logger.isDebugEnabled()) {
logger.debug(fi.toString() + " denied for " + authentication.toString(),
unauthorized);
logger.debug(fi.toString() + " denied for " + authentication.toString(), unauthorized);
}
return false;
@@ -129,4 +120,5 @@ public class DefaultWebInvocationPrivilegeEvaluator implements
return true;
}
}
@@ -36,13 +36,13 @@ import org.springframework.util.Assert;
*
*/
public final class DelegatingAccessDeniedHandler implements AccessDeniedHandler {
private final LinkedHashMap<Class<? extends AccessDeniedException>, AccessDeniedHandler> handlers;
private final AccessDeniedHandler defaultHandler;
/**
* Creates a new instance
*
* @param handlers a map of the {@link AccessDeniedException} class to the
* {@link AccessDeniedHandler} that should be used. Each is considered in the order
* they are specified and only the first {@link AccessDeniedHandler} is ued.
@@ -59,10 +59,8 @@ public final class DelegatingAccessDeniedHandler implements AccessDeniedHandler
}
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException,
ServletException {
for (Entry<Class<? extends AccessDeniedException>, AccessDeniedHandler> entry : handlers
.entrySet()) {
AccessDeniedException accessDeniedException) throws IOException, ServletException {
for (Entry<Class<? extends AccessDeniedException>, AccessDeniedHandler> entry : handlers.entrySet()) {
Class<? extends AccessDeniedException> handlerClass = entry.getKey();
if (handlerClass.isAssignableFrom(accessDeniedException.getClass())) {
AccessDeniedHandler handler = entry.getValue();
@@ -58,13 +58,15 @@ import java.io.IOException;
* <code>authenticationEntryPoint</code> will be launched. If they are not an anonymous
* user, the filter will delegate to the
* {@link org.springframework.security.web.access.AccessDeniedHandler}. By default the
* filter will use {@link org.springframework.security.web.access.AccessDeniedHandlerImpl}.
* filter will use
* {@link org.springframework.security.web.access.AccessDeniedHandlerImpl}.
* <p>
* To use this filter, it is necessary to specify the following properties:
* <ul>
* <li><code>authenticationEntryPoint</code> indicates the handler that should commence
* the authentication process if an <code>AuthenticationException</code> is detected. Note
* that this may also switch the current protocol from http to https for an SSL login.</li>
* that this may also switch the current protocol from http to https for an SSL
* login.</li>
* <li><tt>requestCache</tt> determines the strategy used to save a request during the
* authentication process in order that it may be retrieved and reused once the user has
* authenticated. The default implementation is {@link HttpSessionRequestCache}.</li>
@@ -79,8 +81,11 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
// ================================================================================================
private AccessDeniedHandler accessDeniedHandler = new AccessDeniedHandlerImpl();
private AuthenticationEntryPoint authenticationEntryPoint;
private AuthenticationTrustResolver authenticationTrustResolver = new AuthenticationTrustResolverImpl();
private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();
private RequestCache requestCache = new HttpSessionRequestCache();
@@ -91,10 +96,8 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
this(authenticationEntryPoint, new HttpSessionRequestCache());
}
public ExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint,
RequestCache requestCache) {
Assert.notNull(authenticationEntryPoint,
"authenticationEntryPoint cannot be null");
public ExceptionTranslationFilter(AuthenticationEntryPoint authenticationEntryPoint, RequestCache requestCache) {
Assert.notNull(authenticationEntryPoint, "authenticationEntryPoint cannot be null");
Assert.notNull(requestCache, "requestCache cannot be null");
this.authenticationEntryPoint = authenticationEntryPoint;
this.requestCache = requestCache;
@@ -105,8 +108,7 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
@Override
public void afterPropertiesSet() {
Assert.notNull(authenticationEntryPoint,
"authenticationEntryPoint must be specified");
Assert.notNull(authenticationEntryPoint, "authenticationEntryPoint must be specified");
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
@@ -129,13 +131,15 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
.getFirstThrowableOfType(AuthenticationException.class, causeChain);
if (ase == null) {
ase = (AccessDeniedException) throwableAnalyzer.getFirstThrowableOfType(
AccessDeniedException.class, causeChain);
ase = (AccessDeniedException) throwableAnalyzer.getFirstThrowableOfType(AccessDeniedException.class,
causeChain);
}
if (ase != null) {
if (response.isCommitted()) {
throw new ServletException("Unable to handle the Spring Security Exception because the response is already committed.", ex);
throw new ServletException(
"Unable to handle the Spring Security Exception because the response is already committed.",
ex);
}
handleSpringSecurityException(request, response, chain, ase);
}
@@ -163,46 +167,35 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
return authenticationTrustResolver;
}
private void handleSpringSecurityException(HttpServletRequest request,
HttpServletResponse response, FilterChain chain, RuntimeException exception)
throws IOException, ServletException {
private void handleSpringSecurityException(HttpServletRequest request, HttpServletResponse response,
FilterChain chain, RuntimeException exception) throws IOException, ServletException {
if (exception instanceof AuthenticationException) {
logger.debug(
"Authentication exception occurred; redirecting to authentication entry point",
exception);
logger.debug("Authentication exception occurred; redirecting to authentication entry point", exception);
sendStartAuthentication(request, response, chain,
(AuthenticationException) exception);
sendStartAuthentication(request, response, chain, (AuthenticationException) exception);
}
else if (exception instanceof AccessDeniedException) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authenticationTrustResolver.isAnonymous(authentication) || authenticationTrustResolver.isRememberMe(authentication)) {
logger.debug(
"Access is denied (user is " + (authenticationTrustResolver.isAnonymous(authentication) ? "anonymous" : "not fully authenticated") + "); redirecting to authentication entry point",
if (authenticationTrustResolver.isAnonymous(authentication)
|| authenticationTrustResolver.isRememberMe(authentication)) {
logger.debug("Access is denied (user is " + (authenticationTrustResolver.isAnonymous(authentication)
? "anonymous" : "not fully authenticated") + "); redirecting to authentication entry point",
exception);
sendStartAuthentication(
request,
response,
chain,
sendStartAuthentication(request, response, chain,
new InsufficientAuthenticationException(
messages.getMessage(
"ExceptionTranslationFilter.insufficientAuthentication",
"Full authentication is required to access this resource")));
messages.getMessage("ExceptionTranslationFilter.insufficientAuthentication",
"Full authentication is required to access this resource")));
}
else {
logger.debug(
"Access is denied (user is not anonymous); delegating to AccessDeniedHandler",
exception);
logger.debug("Access is denied (user is not anonymous); delegating to AccessDeniedHandler", exception);
accessDeniedHandler.handle(request, response,
(AccessDeniedException) exception);
accessDeniedHandler.handle(request, response, (AccessDeniedException) exception);
}
}
}
protected void sendStartAuthentication(HttpServletRequest request,
HttpServletResponse response, FilterChain chain,
protected void sendStartAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
AuthenticationException reason) throws ServletException, IOException {
// SEC-112: Clear the SecurityContextHolder's Authentication, as the
// existing Authentication is no longer considered valid
@@ -217,10 +210,8 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
this.accessDeniedHandler = accessDeniedHandler;
}
public void setAuthenticationTrustResolver(
AuthenticationTrustResolver authenticationTrustResolver) {
Assert.notNull(authenticationTrustResolver,
"authenticationTrustResolver must not be null");
public void setAuthenticationTrustResolver(AuthenticationTrustResolver authenticationTrustResolver) {
Assert.notNull(authenticationTrustResolver, "authenticationTrustResolver must not be null");
this.authenticationTrustResolver = authenticationTrustResolver;
}
@@ -234,6 +225,7 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
* unwrapping <code>ServletException</code>s.
*/
private static final class DefaultThrowableAnalyzer extends ThrowableAnalyzer {
/**
* @see org.springframework.security.web.util.ThrowableAnalyzer#initExtractorMap()
*/
@@ -241,8 +233,7 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
super.initExtractorMap();
registerExtractor(ServletException.class, throwable -> {
ThrowableAnalyzer.verifyThrowableHierarchy(throwable,
ServletException.class);
ThrowableAnalyzer.verifyThrowableHierarchy(throwable, ServletException.class);
return ((ServletException) throwable).getRootCause();
});
}
@@ -36,21 +36,20 @@ import org.springframework.util.Assert;
*
*/
public final class RequestMatcherDelegatingAccessDeniedHandler implements AccessDeniedHandler {
private final LinkedHashMap<RequestMatcher, AccessDeniedHandler> handlers;
private final AccessDeniedHandler defaultHandler;
/**
* Creates a new instance
*
* @param handlers a map of {@link RequestMatcher}s to
* {@link AccessDeniedHandler}s that should be used. Each is considered in the order
* they are specified and only the first {@link AccessDeniedHandler} is used.
* @param handlers a map of {@link RequestMatcher}s to {@link AccessDeniedHandler}s
* that should be used. Each is considered in the order they are specified and only
* the first {@link AccessDeniedHandler} is used.
* @param defaultHandler the default {@link AccessDeniedHandler} that should be used
* if none of the matchers match.
*/
public RequestMatcherDelegatingAccessDeniedHandler(
LinkedHashMap<RequestMatcher, AccessDeniedHandler> handlers,
public RequestMatcherDelegatingAccessDeniedHandler(LinkedHashMap<RequestMatcher, AccessDeniedHandler> handlers,
AccessDeniedHandler defaultHandler) {
Assert.notEmpty(handlers, "handlers cannot be null or empty");
Assert.notNull(defaultHandler, "defaultHandler cannot be null");
@@ -59,10 +58,8 @@ public final class RequestMatcherDelegatingAccessDeniedHandler implements Access
}
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException,
ServletException {
for (Entry<RequestMatcher, AccessDeniedHandler> entry : this.handlers
.entrySet()) {
AccessDeniedException accessDeniedException) throws IOException, ServletException {
for (Entry<RequestMatcher, AccessDeniedHandler> entry : this.handlers.entrySet()) {
RequestMatcher matcher = entry.getKey();
if (matcher.matches(request)) {
AccessDeniedHandler handler = entry.getValue();
@@ -29,7 +29,6 @@ public interface WebInvocationPrivilegeEvaluator {
/**
* Determines whether the user represented by the supplied <tt>Authentication</tt>
* object is allowed to invoke the supplied URI.
*
* @param uri the URI excluding the context path (a default context path setting will
* be used)
*/
@@ -44,7 +43,6 @@ public interface WebInvocationPrivilegeEvaluator {
* metadata applies to a given request URI, so generally the <code>contextPath</code>
* is unimportant unless you are using a custom
* <code>FilterInvocationSecurityMetadataSource</code>.
*
* @param uri the URI excluding the context path
* @param contextPath the context path (may be null).
* @param method the HTTP method (or null, for any method)
@@ -53,4 +51,5 @@ public interface WebInvocationPrivilegeEvaluator {
* @return true if access is allowed, false if denied
*/
boolean isAllowed(String contextPath, String uri, String method, Authentication authentication);
}
@@ -29,6 +29,7 @@ import java.io.IOException;
* @author Luke Taylor
*/
public abstract class AbstractRetryEntryPoint implements ChannelEntryPoint {
// ~ Static fields/initializers
// =====================================================================================
protected final Log logger = LogFactory.getLog(getClass());
@@ -37,9 +38,12 @@ public abstract class AbstractRetryEntryPoint implements ChannelEntryPoint {
// ================================================================================================
private PortMapper portMapper = new PortMapperImpl();
private PortResolver portResolver = new PortResolverImpl();
/** The scheme ("http://" or "https://") */
private final String scheme;
/** The standard port for the scheme (80 for http, 443 for https) */
private final int standardPort;
@@ -56,11 +60,9 @@ public abstract class AbstractRetryEntryPoint implements ChannelEntryPoint {
// ~ Methods
// ========================================================================================================
public void commence(HttpServletRequest request, HttpServletResponse response)
throws IOException {
public void commence(HttpServletRequest request, HttpServletResponse response) throws IOException {
String queryString = request.getQueryString();
String redirectUrl = request.getRequestURI()
+ ((queryString == null) ? "" : ("?" + queryString));
String redirectUrl = request.getRequestURI() + ((queryString == null) ? "" : ("?" + queryString));
Integer currentPort = portResolver.getServerPort(request);
Integer redirectPort = getMappedPort(currentPort);
@@ -68,8 +70,7 @@ public abstract class AbstractRetryEntryPoint implements ChannelEntryPoint {
if (redirectPort != null) {
boolean includePort = redirectPort != standardPort;
redirectUrl = scheme + request.getServerName()
+ ((includePort) ? (":" + redirectPort) : "") + redirectUrl;
redirectUrl = scheme + request.getServerName() + ((includePort) ? (":" + redirectPort) : "") + redirectUrl;
}
if (logger.isDebugEnabled()) {
@@ -102,7 +103,6 @@ public abstract class AbstractRetryEntryPoint implements ChannelEntryPoint {
/**
* Sets the strategy to be used for redirecting to the required channel URL. A
* {@code DefaultRedirectStrategy} instance will be used if not set.
*
* @param redirectStrategy the strategy instance to which the URL will be passed.
*/
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
@@ -113,4 +113,5 @@ public abstract class AbstractRetryEntryPoint implements ChannelEntryPoint {
protected final RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
@@ -30,6 +30,7 @@ import javax.servlet.ServletException;
* @author Ben Alex
*/
public interface ChannelDecisionManager {
// ~ Methods
// ========================================================================================================
@@ -38,8 +39,7 @@ public interface ChannelDecisionManager {
* level of channel security based on the requested list of <tt>ConfigAttribute</tt>s.
*
*/
void decide(FilterInvocation invocation, Collection<ConfigAttribute> config)
throws IOException, ServletException;
void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException;
/**
* Indicates whether this <code>ChannelDecisionManager</code> is able to process the
@@ -48,12 +48,11 @@ public interface ChannelDecisionManager {
* This allows the <code>ChannelProcessingFilter</code> to check every configuration
* attribute can be consumed by the configured <code>ChannelDecisionManager</code>.
* </p>
*
* @param attribute a configuration attribute that has been configured against the
* <code>ChannelProcessingFilter</code>
*
* @return true if this <code>ChannelDecisionManager</code> can support the passed
* configuration attribute
*/
boolean supports(ConfigAttribute attribute);
}
@@ -47,8 +47,7 @@ import javax.servlet.ServletException;
*
* @author Ben Alex
*/
public class ChannelDecisionManagerImpl implements ChannelDecisionManager,
InitializingBean {
public class ChannelDecisionManagerImpl implements ChannelDecisionManager, InitializingBean {
public static final String ANY_CHANNEL = "ANY_CHANNEL";
@@ -91,9 +90,8 @@ public class ChannelDecisionManagerImpl implements ChannelDecisionManager,
channelProcessors = new ArrayList<>(newList.size());
for (Object currentObject : newList) {
Assert.isInstanceOf(ChannelProcessor.class, currentObject,
() -> "ChannelProcessor " + currentObject.getClass().getName()
+ " must implement ChannelProcessor");
Assert.isInstanceOf(ChannelProcessor.class, currentObject, () -> "ChannelProcessor "
+ currentObject.getClass().getName() + " must implement ChannelProcessor");
channelProcessors.add((ChannelProcessor) currentObject);
}
}
@@ -111,4 +109,5 @@ public class ChannelDecisionManagerImpl implements ChannelDecisionManager,
return false;
}
}
@@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Ben Alex
*/
public interface ChannelEntryPoint {
// ~ Methods
// ========================================================================================================
@@ -41,11 +42,10 @@ public interface ChannelEntryPoint {
* Implementations should modify the headers on the <code>ServletResponse</code> as
* necessary to commence the user agent using the implementation's supported channel
* type.
*
* @param request that a <code>ChannelProcessor</code> has rejected
* @param response so that the user agent can begin using a new channel
*
*/
void commence(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
void commence(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
}
@@ -89,6 +89,7 @@ public class ChannelProcessingFilter extends GenericFilterBean {
// ================================================================================================
private ChannelDecisionManager channelDecisionManager;
private FilterInvocationSecurityMetadataSource securityMetadataSource;
// ~ Methods
@@ -96,18 +97,15 @@ public class ChannelProcessingFilter extends GenericFilterBean {
@Override
public void afterPropertiesSet() {
Assert.notNull(this.securityMetadataSource,
"securityMetadataSource must be specified");
Assert.notNull(this.channelDecisionManager,
"channelDecisionManager must be specified");
Assert.notNull(this.securityMetadataSource, "securityMetadataSource must be specified");
Assert.notNull(this.channelDecisionManager, "channelDecisionManager must be specified");
Collection<ConfigAttribute> attrDefs = this.securityMetadataSource
.getAllConfigAttributes();
Collection<ConfigAttribute> attrDefs = this.securityMetadataSource.getAllConfigAttributes();
if (attrDefs == null) {
if (this.logger.isWarnEnabled()) {
this.logger
.warn("Could not validate configuration attributes as the FilterInvocationSecurityMetadataSource did "
this.logger.warn(
"Could not validate configuration attributes as the FilterInvocationSecurityMetadataSource did "
+ "not return any attributes");
}
@@ -128,8 +126,7 @@ public class ChannelProcessingFilter extends GenericFilterBean {
}
}
else {
throw new IllegalArgumentException(
"Unsupported configuration attributes: " + unsupportedAttributes);
throw new IllegalArgumentException("Unsupported configuration attributes: " + unsupportedAttributes);
}
}
@@ -143,8 +140,7 @@ public class ChannelProcessingFilter extends GenericFilterBean {
if (attr != null) {
if (this.logger.isDebugEnabled()) {
this.logger.debug(
"Request: " + fi.toString() + "; ConfigAttributes: " + attr);
this.logger.debug("Request: " + fi.toString() + "; ConfigAttributes: " + attr);
}
this.channelDecisionManager.decide(fi, attr);
@@ -173,4 +169,5 @@ public class ChannelProcessingFilter extends GenericFilterBean {
FilterInvocationSecurityMetadataSource filterInvocationSecurityMetadataSource) {
this.securityMetadataSource = filterInvocationSecurityMetadataSource;
}
}
@@ -36,6 +36,7 @@ import javax.servlet.ServletException;
* @author Ben Alex
*/
public interface ChannelProcessor {
// ~ Methods
// ========================================================================================================
@@ -44,8 +45,7 @@ public interface ChannelProcessor {
* level of channel security based on the requested list of <tt>ConfigAttribute</tt>s.
*
*/
void decide(FilterInvocation invocation, Collection<ConfigAttribute> config)
throws IOException, ServletException;
void decide(FilterInvocation invocation, Collection<ConfigAttribute> config) throws IOException, ServletException;
/**
* Indicates whether this <code>ChannelProcessor</code> is able to process the passed
@@ -53,12 +53,11 @@ public interface ChannelProcessor {
* <p>
* This allows the <code>ChannelProcessingFilter</code> to check every configuration
* attribute can be consumed by the configured <code>ChannelDecisionManager</code>.
*
* @param attribute a configuration attribute that has been configured against the
* <tt>ChannelProcessingFilter</tt>.
*
* @return true if this <code>ChannelProcessor</code> can support the passed
* configuration attribute
*/
boolean supports(ConfigAttribute attribute);
}
@@ -41,10 +41,12 @@ import org.springframework.util.Assert;
* @author Ben Alex
*/
public class InsecureChannelProcessor implements InitializingBean, ChannelProcessor {
// ~ Instance fields
// ================================================================================================
private ChannelEntryPoint entryPoint = new RetryWithHttpEntryPoint();
private String insecureKeyword = "REQUIRES_INSECURE_CHANNEL";
// ~ Methods
@@ -64,8 +66,7 @@ public class InsecureChannelProcessor implements InitializingBean, ChannelProces
for (ConfigAttribute attribute : config) {
if (supports(attribute)) {
if (invocation.getHttpRequest().isSecure()) {
entryPoint
.commence(invocation.getRequest(), invocation.getResponse());
entryPoint.commence(invocation.getRequest(), invocation.getResponse());
}
}
}
@@ -91,4 +92,5 @@ public class InsecureChannelProcessor implements InitializingBean, ChannelProces
return (attribute != null) && (attribute.getAttribute() != null)
&& attribute.getAttribute().equals(getInsecureKeyword());
}
}
@@ -34,4 +34,5 @@ public class RetryWithHttpEntryPoint extends AbstractRetryEntryPoint {
protected Integer getMappedPort(Integer mapFromPort) {
return getPortMapper().lookupHttpPort(mapFromPort);
}
}
@@ -35,4 +35,5 @@ public class RetryWithHttpsEntryPoint extends AbstractRetryEntryPoint {
protected Integer getMappedPort(Integer mapFromPort) {
return getPortMapper().lookupHttpsPort(mapFromPort);
}
}
@@ -41,10 +41,12 @@ import org.springframework.util.Assert;
* @author Ben Alex
*/
public class SecureChannelProcessor implements InitializingBean, ChannelProcessor {
// ~ Instance fields
// ================================================================================================
private ChannelEntryPoint entryPoint = new RetryWithHttpsEntryPoint();
private String secureKeyword = "REQUIRES_SECURE_CHANNEL";
// ~ Methods
@@ -57,14 +59,12 @@ public class SecureChannelProcessor implements InitializingBean, ChannelProcesso
public void decide(FilterInvocation invocation, Collection<ConfigAttribute> config)
throws IOException, ServletException {
Assert.isTrue((invocation != null) && (config != null),
"Nulls cannot be provided");
Assert.isTrue((invocation != null) && (config != null), "Nulls cannot be provided");
for (ConfigAttribute attribute : config) {
if (supports(attribute)) {
if (!invocation.getHttpRequest().isSecure()) {
entryPoint
.commence(invocation.getRequest(), invocation.getResponse());
entryPoint.commence(invocation.getRequest(), invocation.getResponse());
}
}
}
@@ -90,4 +90,5 @@ public class SecureChannelProcessor implements InitializingBean, ChannelProcesso
return (attribute != null) && (attribute.getAttribute() != null)
&& attribute.getAttribute().equals(getSecureKeyword());
}
}
@@ -19,4 +19,3 @@
* Most commonly used to enforce that requests are submitted over HTTP or HTTPS.
*/
package org.springframework.security.web.access.channel;
@@ -39,8 +39,7 @@ abstract class AbstractVariableEvaluationContextPostProcessor
implements EvaluationContextPostProcessor<FilterInvocation> {
@Override
public final EvaluationContext postProcess(EvaluationContext context,
FilterInvocation invocation) {
public final EvaluationContext postProcess(EvaluationContext context, FilterInvocation invocation) {
final HttpServletRequest request = invocation.getHttpRequest();
return new DelegatingEvaluationContext(context) {
private Map<String, String> variables;
@@ -25,21 +25,20 @@ import org.springframework.security.web.FilterInvocation;
import org.springframework.util.Assert;
/**
*
* @author Luke Taylor
* @author Eddú Meléndez
* @since 3.0
*/
public class DefaultWebSecurityExpressionHandler extends
AbstractSecurityExpressionHandler<FilterInvocation> implements
SecurityExpressionHandler<FilterInvocation> {
public class DefaultWebSecurityExpressionHandler extends AbstractSecurityExpressionHandler<FilterInvocation>
implements SecurityExpressionHandler<FilterInvocation> {
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
private String defaultRolePrefix = "ROLE_";
@Override
protected SecurityExpressionOperations createSecurityExpressionRoot(
Authentication authentication, FilterInvocation fi) {
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
FilterInvocation fi) {
WebSecurityExpressionRoot root = new WebSecurityExpressionRoot(authentication, fi);
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(trustResolver);
@@ -51,7 +50,6 @@ public class DefaultWebSecurityExpressionHandler extends
/**
* Sets the {@link AuthenticationTrustResolver} to be used. The default is
* {@link AuthenticationTrustResolverImpl}.
*
* @param trustResolver the {@link AuthenticationTrustResolver} to use. Cannot be
* null.
*/
@@ -62,19 +60,21 @@ public class DefaultWebSecurityExpressionHandler extends
/**
* <p>
* Sets the default prefix to be added to {@link org.springframework.security.access.expression.SecurityExpressionRoot#hasAnyRole(String...)} or
* {@link org.springframework.security.access.expression.SecurityExpressionRoot#hasRole(String)}. For example, if hasRole("ADMIN") or hasRole("ROLE_ADMIN")
* is passed in, then the role ROLE_ADMIN will be used when the defaultRolePrefix is
* "ROLE_" (default).
* Sets the default prefix to be added to
* {@link org.springframework.security.access.expression.SecurityExpressionRoot#hasAnyRole(String...)}
* or
* {@link org.springframework.security.access.expression.SecurityExpressionRoot#hasRole(String)}.
* For example, if hasRole("ADMIN") or hasRole("ROLE_ADMIN") is passed in, then the
* role ROLE_ADMIN will be used when the defaultRolePrefix is "ROLE_" (default).
* </p>
*
* <p>
* If null or empty, then no default role prefix is used.
* </p>
*
* @param defaultRolePrefix the default prefix to add to roles. Default "ROLE_".
*/
public void setDefaultRolePrefix(String defaultRolePrefix) {
this.defaultRolePrefix = defaultRolePrefix;
}
}
@@ -36,6 +36,7 @@ import org.springframework.expression.TypedValue;
* @since 4.1
*/
class DelegatingEvaluationContext implements EvaluationContext {
private final EvaluationContext delegate;
DelegatingEvaluationContext(EvaluationContext delegate) {
@@ -96,4 +97,5 @@ class DelegatingEvaluationContext implements EvaluationContext {
public Object lookupVariable(String name) {
return this.delegate.lookupVariable(name);
}
}
@@ -16,10 +16,10 @@
package org.springframework.security.web.access.expression;
import org.springframework.expression.EvaluationContext;
/**
*
/**
* Allows post processing the {@link EvaluationContext}
* /** Allows post processing the {@link EvaluationContext}
*
* <p>
* This API is intentionally kept package scope as it may evolve over time.
@@ -32,15 +32,13 @@ import org.springframework.expression.EvaluationContext;
interface EvaluationContextPostProcessor<I> {
/**
* Allows post processing of the {@link EvaluationContext}. Implementations
* may return a new instance of {@link EvaluationContext} or modify the
* {@link EvaluationContext} that was passed in.
*
* @param context
* the original {@link EvaluationContext}
* @param invocation
* the security invocation object (i.e. FilterInvocation)
* Allows post processing of the {@link EvaluationContext}. Implementations may return
* a new instance of {@link EvaluationContext} or modify the {@link EvaluationContext}
* that was passed in.
* @param context the original {@link EvaluationContext}
* @param invocation the security invocation object (i.e. FilterInvocation)
* @return the upated context.
*/
EvaluationContext postProcess(EvaluationContext context, I invocation);
}
@@ -44,45 +44,36 @@ import org.springframework.util.Assert;
*/
public final class ExpressionBasedFilterInvocationSecurityMetadataSource
extends DefaultFilterInvocationSecurityMetadataSource {
private final static Log logger = LogFactory
.getLog(ExpressionBasedFilterInvocationSecurityMetadataSource.class);
private final static Log logger = LogFactory.getLog(ExpressionBasedFilterInvocationSecurityMetadataSource.class);
public ExpressionBasedFilterInvocationSecurityMetadataSource(
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap,
SecurityExpressionHandler<FilterInvocation> expressionHandler) {
super(processMap(requestMap, expressionHandler.getExpressionParser()));
Assert.notNull(expressionHandler,
"A non-null SecurityExpressionHandler is required");
Assert.notNull(expressionHandler, "A non-null SecurityExpressionHandler is required");
}
private static LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> processMap(
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap,
ExpressionParser parser) {
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap, ExpressionParser parser) {
Assert.notNull(parser, "SecurityExpressionHandler returned a null parser object");
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestToExpressionAttributesMap = new LinkedHashMap<>(
requestMap);
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
.entrySet()) {
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap.entrySet()) {
RequestMatcher request = entry.getKey();
Assert.isTrue(entry.getValue().size() == 1,
() -> "Expected a single expression attribute for " + request);
Assert.isTrue(entry.getValue().size() == 1, () -> "Expected a single expression attribute for " + request);
ArrayList<ConfigAttribute> attributes = new ArrayList<>(1);
String expression = entry.getValue().toArray(new ConfigAttribute[1])[0]
.getAttribute();
logger.debug("Adding web access control expression '" + expression + "', for "
+ request);
String expression = entry.getValue().toArray(new ConfigAttribute[1])[0].getAttribute();
logger.debug("Adding web access control expression '" + expression + "', for " + request);
AbstractVariableEvaluationContextPostProcessor postProcessor = createPostProcessor(
request);
AbstractVariableEvaluationContextPostProcessor postProcessor = createPostProcessor(request);
try {
attributes.add(new WebExpressionConfigAttribute(
parser.parseExpression(expression), postProcessor));
attributes.add(new WebExpressionConfigAttribute(parser.parseExpression(expression), postProcessor));
}
catch (ParseException e) {
throw new IllegalArgumentException(
"Failed to parse expression '" + expression + "'");
throw new IllegalArgumentException("Failed to parse expression '" + expression + "'");
}
requestToExpressionAttributesMap.put(request, attributes);
@@ -95,12 +86,11 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource
return new RequestVariablesExtractorEvaluationContextPostProcessor(request);
}
static class AntPathMatcherEvaluationContextPostProcessor
extends AbstractVariableEvaluationContextPostProcessor {
static class AntPathMatcherEvaluationContextPostProcessor extends AbstractVariableEvaluationContextPostProcessor {
private final AntPathRequestMatcher matcher;
AntPathMatcherEvaluationContextPostProcessor(
AntPathRequestMatcher matcher) {
AntPathMatcherEvaluationContextPostProcessor(AntPathRequestMatcher matcher) {
this.matcher = matcher;
}
@@ -108,14 +98,15 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource
Map<String, String> extractVariables(HttpServletRequest request) {
return this.matcher.matcher(request).getVariables();
}
}
static class RequestVariablesExtractorEvaluationContextPostProcessor
extends AbstractVariableEvaluationContextPostProcessor {
private final RequestMatcher matcher;
RequestVariablesExtractorEvaluationContextPostProcessor(
RequestMatcher matcher) {
RequestVariablesExtractorEvaluationContextPostProcessor(RequestMatcher matcher) {
this.matcher = matcher;
}
@@ -123,6 +114,7 @@ public final class ExpressionBasedFilterInvocationSecurityMetadataSource
Map<String, String> extractVariables(HttpServletRequest request) {
return this.matcher.matcher(request).getVariables();
}
}
}
@@ -26,9 +26,10 @@ import org.springframework.security.web.FilterInvocation;
* @author Luke Taylor
* @since 3.0
*/
class WebExpressionConfigAttribute implements ConfigAttribute,
EvaluationContextPostProcessor<FilterInvocation> {
class WebExpressionConfigAttribute implements ConfigAttribute, EvaluationContextPostProcessor<FilterInvocation> {
private final Expression authorizeExpression;
private final EvaluationContextPostProcessor<FilterInvocation> postProcessor;
WebExpressionConfigAttribute(Expression authorizeExpression,
@@ -43,8 +44,7 @@ class WebExpressionConfigAttribute implements ConfigAttribute,
@Override
public EvaluationContext postProcess(EvaluationContext context, FilterInvocation fi) {
return this.postProcessor == null ? context
: this.postProcessor.postProcess(context, fi);
return this.postProcessor == null ? context : this.postProcessor.postProcess(context, fi);
}
@Override
@@ -56,4 +56,5 @@ class WebExpressionConfigAttribute implements ConfigAttribute,
public String toString() {
return this.authorizeExpression.getExpressionString();
}
}
@@ -27,14 +27,15 @@ import org.springframework.security.web.FilterInvocation;
/**
* Voter which handles web authorisation decisions.
*
* @author Luke Taylor
* @since 3.0
*/
public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation> {
private SecurityExpressionHandler<FilterInvocation> expressionHandler = new DefaultWebSecurityExpressionHandler();
public int vote(Authentication authentication, FilterInvocation fi,
Collection<ConfigAttribute> attributes) {
public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
assert authentication != null;
assert fi != null;
assert attributes != null;
@@ -45,16 +46,13 @@ public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation>
return ACCESS_ABSTAIN;
}
EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication,
fi);
EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication, fi);
ctx = weca.postProcess(ctx, fi);
return ExpressionUtils.evaluateAsBoolean(weca.getAuthorizeExpression(), ctx) ? ACCESS_GRANTED
: ACCESS_DENIED;
return ExpressionUtils.evaluateAsBoolean(weca.getAuthorizeExpression(), ctx) ? ACCESS_GRANTED : ACCESS_DENIED;
}
private WebExpressionConfigAttribute findConfigAttribute(
Collection<ConfigAttribute> attributes) {
private WebExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
for (ConfigAttribute attribute : attributes) {
if (attribute instanceof WebExpressionConfigAttribute) {
return (WebExpressionConfigAttribute) attribute;
@@ -71,8 +69,8 @@ public class WebExpressionVoter implements AccessDecisionVoter<FilterInvocation>
return FilterInvocation.class.isAssignableFrom(clazz);
}
public void setExpressionHandler(
SecurityExpressionHandler<FilterInvocation> expressionHandler) {
public void setExpressionHandler(SecurityExpressionHandler<FilterInvocation> expressionHandler) {
this.expressionHandler = expressionHandler;
}
}
@@ -23,11 +23,11 @@ import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.util.matcher.IpAddressMatcher;
/**
*
* @author Luke Taylor
* @since 3.0
*/
public class WebSecurityExpressionRoot extends SecurityExpressionRoot {
// private FilterInvocation filterInvocation;
/** Allows direct access to the request object */
public final HttpServletRequest request;
@@ -41,7 +41,6 @@ public class WebSecurityExpressionRoot extends SecurityExpressionRoot {
/**
* Takes a specific IP address or a range using the IP/Netmask (e.g. 192.168.1.0/24 or
* 202.24.0.0/14).
*
* @param ipAddress the address or range of addresses from which the request must
* come.
* @return true if the IP address of the current request is in the required range.
@@ -17,4 +17,3 @@
* Implementation of web security expressions.
*/
package org.springframework.security.web.access.expression;
@@ -44,15 +44,13 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
* <p>
* The most common method creating an instance is using the Spring Security namespace. For
* example, the {@code pattern} and {@code access} attributes of the
* {@code <intercept-url>} elements defined as children of the {@code <http>}
* element are combined to build the instance used by the
* {@code FilterSecurityInterceptor}.
* {@code <intercept-url>} elements defined as children of the {@code <http>} element are
* combined to build the instance used by the {@code FilterSecurityInterceptor}.
*
* @author Ben Alex
* @author Luke Taylor
*/
public class DefaultFilterInvocationSecurityMetadataSource implements
FilterInvocationSecurityMetadataSource {
public class DefaultFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
protected final Log logger = LogFactory.getLog(getClass());
@@ -65,7 +63,6 @@ public class DefaultFilterInvocationSecurityMetadataSource implements
* Sets the internal request map from the supplied map. The key elements should be of
* type {@link RequestMatcher}, which. The path stored in the key will depend on the
* type of the supplied UrlMatcher.
*
* @param requestMap order-preserving map of request definitions to attribute lists
*/
public DefaultFilterInvocationSecurityMetadataSource(
@@ -80,8 +77,7 @@ public class DefaultFilterInvocationSecurityMetadataSource implements
public Collection<ConfigAttribute> getAllConfigAttributes() {
Set<ConfigAttribute> allAttributes = new HashSet<>();
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
.entrySet()) {
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap.entrySet()) {
allAttributes.addAll(entry.getValue());
}
@@ -90,8 +86,7 @@ public class DefaultFilterInvocationSecurityMetadataSource implements
public Collection<ConfigAttribute> getAttributes(Object object) {
final HttpServletRequest request = ((FilterInvocation) object).getRequest();
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
.entrySet()) {
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap.entrySet()) {
if (entry.getKey().matches(request)) {
return entry.getValue();
}
@@ -102,4 +97,5 @@ public class DefaultFilterInvocationSecurityMetadataSource implements
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
}
@@ -26,4 +26,5 @@ import org.springframework.security.web.FilterInvocation;
* @author Ben Alex
*/
public interface FilterInvocationSecurityMetadataSource extends SecurityMetadataSource {
}
@@ -42,8 +42,8 @@ import org.springframework.security.web.FilterInvocation;
* @author Ben Alex
* @author Rob Winch
*/
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements
Filter {
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
// ~ Static fields/initializers
// =====================================================================================
@@ -53,6 +53,7 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
// ================================================================================================
private FilterInvocationSecurityMetadataSource securityMetadataSource;
private boolean observeOncePerRequest = true;
// ~ Methods
@@ -60,7 +61,6 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
/**
* Not used (we rely on IoC container lifecycle services instead)
*
* @param arg0 ignored
*
*/
@@ -76,16 +76,14 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
/**
* Method that is actually called by the filter chain. Simply delegates to the
* {@link #invoke(FilterInvocation)} method.
*
* @param request the servlet request
* @param response the servlet response
* @param chain the filter chain
*
* @throws IOException if the filter chain fails
* @throws ServletException if the filter chain fails
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
@@ -107,8 +105,7 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
}
public void invoke(FilterInvocation fi) throws IOException, ServletException {
if ((fi.getRequest() != null)
&& (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
if ((fi.getRequest() != null) && (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
&& observeOncePerRequest) {
// filter already applied to this request and user wants us to observe
// once-per-request handling, so don't re-do security checking
@@ -139,7 +136,6 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
* execute once-per-request. Sometimes users may wish it to execute more than once per
* request, such as when JSP forwards are being used and filter security is desired on
* each included fragment of the HTTP request.
*
* @return <code>true</code> (the default) if once-per-request is honoured, otherwise
* <code>false</code> if <code>FilterSecurityInterceptor</code> will enforce
* authorizations for each and every fragment of the HTTP request.
@@ -151,4 +147,5 @@ public class FilterSecurityInterceptor extends AbstractSecurityInterceptor imple
public void setObserveOncePerRequest(boolean observeOncePerRequest) {
this.observeOncePerRequest = observeOncePerRequest;
}
}
@@ -22,7 +22,9 @@ import org.springframework.util.Assert;
* @since 2.0
*/
public class RequestKey {
private final String url;
private final String method;
public RequestKey(String url) {
@@ -81,4 +83,5 @@ public class RequestKey {
return sb.toString();
}
}
@@ -17,4 +17,3 @@
* Enforcement of security for HTTP requests, typically by the URL requested.
*/
package org.springframework.security.web.access.intercept;
@@ -17,4 +17,3 @@
* Access-control related classes and packages.
*/
package org.springframework.security.web.access;
@@ -100,16 +100,16 @@ import org.springframework.web.filter.GenericFilterBean;
*
* The class has an optional {@link SessionAuthenticationStrategy} which will be invoked
* immediately after a successful call to {@code attemptAuthentication()}. Different
* implementations
* {@link #setSessionAuthenticationStrategy(SessionAuthenticationStrategy) can be
* injected} to enable things like session-fixation attack prevention or to control the
* number of simultaneous sessions a principal may have.
* implementations {@link #setSessionAuthenticationStrategy(SessionAuthenticationStrategy)
* can be injected} to enable things like session-fixation attack prevention or to control
* the number of simultaneous sessions a principal may have.
*
* @author Ben Alex
* @author Luke Taylor
*/
public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean
implements ApplicationEventPublisherAware, MessageSourceAware {
// ~ Static fields/initializers
// =====================================================================================
@@ -117,9 +117,13 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
// ================================================================================================
protected ApplicationEventPublisher eventPublisher;
protected AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
private AuthenticationManager authenticationManager;
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private RememberMeServices rememberMeServices = new NullRememberMeServices();
private RequestMatcher requiresAuthenticationRequestMatcher;
@@ -131,6 +135,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
private boolean allowSessionCreation = true;
private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
// ~ Constructors
@@ -145,23 +150,20 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
/**
* Creates a new instance
*
* @param requiresAuthenticationRequestMatcher the {@link RequestMatcher} used to
* determine if authentication is required. Cannot be null.
*/
protected AbstractAuthenticationProcessingFilter(
RequestMatcher requiresAuthenticationRequestMatcher) {
Assert.notNull(requiresAuthenticationRequestMatcher,
"requiresAuthenticationRequestMatcher cannot be null");
protected AbstractAuthenticationProcessingFilter(RequestMatcher requiresAuthenticationRequestMatcher) {
Assert.notNull(requiresAuthenticationRequestMatcher, "requiresAuthenticationRequestMatcher cannot be null");
this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
}
/**
* Creates a new instance with a default filterProcessesUrl and an {@link AuthenticationManager}
*
* Creates a new instance with a default filterProcessesUrl and an
* {@link AuthenticationManager}
* @param defaultFilterProcessesUrl the default value for <tt>filterProcessesUrl</tt>.
* @param authenticationManager the {@link AuthenticationManager} used to authenticate an {@link Authentication} object.
* Cannot be null.
* @param authenticationManager the {@link AuthenticationManager} used to authenticate
* an {@link Authentication} object. Cannot be null.
*/
protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl,
AuthenticationManager authenticationManager) {
@@ -170,12 +172,12 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
}
/**
* Creates a new instance with a {@link RequestMatcher} and an {@link AuthenticationManager}
*
* @param requiresAuthenticationRequestMatcher the {@link RequestMatcher} used to determine
* if authentication is required. Cannot be null.
* @param authenticationManager the {@link AuthenticationManager} used to authenticate an {@link Authentication} object.
* Cannot be null.
* Creates a new instance with a {@link RequestMatcher} and an
* {@link AuthenticationManager}
* @param requiresAuthenticationRequestMatcher the {@link RequestMatcher} used to
* determine if authentication is required. Cannot be null.
* @param authenticationManager the {@link AuthenticationManager} used to authenticate
* an {@link Authentication} object. Cannot be null.
*/
protected AbstractAuthenticationProcessingFilter(RequestMatcher requiresAuthenticationRequestMatcher,
AuthenticationManager authenticationManager) {
@@ -192,12 +194,10 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
}
/**
* Invokes the
* {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse)
* Invokes the {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse)
* requiresAuthentication} method to determine whether the request is for
* authentication and should be handled by this filter. If it is an authentication
* request, the
* {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse)
* request, the {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse)
* attemptAuthentication} will be invoked to perform the authentication. There are
* then three possible outcomes:
* <ol>
@@ -245,9 +245,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
sessionStrategy.onAuthentication(authResult, request, response);
}
catch (InternalAuthenticationServiceException failed) {
logger.error(
"An internal error occurred while trying to authenticate the user.",
failed);
logger.error("An internal error occurred while trying to authenticate the user.", failed);
unsuccessfulAuthentication(request, response, failed);
return;
@@ -276,12 +274,10 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* before matching against the <code>filterProcessesUrl</code> property.
* <p>
* Subclasses may override for special requirements, such as Tapestry integration.
*
* @return <code>true</code> if the filter should attempt authentication,
* <code>false</code> otherwise.
*/
protected boolean requiresAuthentication(HttpServletRequest request,
HttpServletResponse response) {
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return requiresAuthenticationRequestMatcher.matches(request);
}
@@ -295,20 +291,17 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* <li>Return null, indicating that the authentication process is still in progress.
* Before returning, the implementation should perform any additional work required to
* complete the process.</li>
* <li>Throw an <tt>AuthenticationException</tt> if the authentication process fails</li>
* <li>Throw an <tt>AuthenticationException</tt> if the authentication process
* fails</li>
* </ol>
*
* @param request from which to extract parameters and perform the authentication
* @param response the response, which may be needed if the implementation has to do a
* redirect as part of a multi-stage authentication process (such as OpenID).
*
* @return the authenticated user token, or null if authentication is incomplete.
*
* @throws AuthenticationException if authentication fails.
*/
public abstract Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException, IOException,
ServletException;
public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException;
/**
* Default behaviour for successful authentication.
@@ -318,7 +311,8 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* <li>Informs the configured <tt>RememberMeServices</tt> of the successful login</li>
* <li>Fires an {@link InteractiveAuthenticationSuccessEvent} via the configured
* <tt>ApplicationEventPublisher</tt></li>
* <li>Delegates additional behaviour to the {@link AuthenticationSuccessHandler}.</li>
* <li>Delegates additional behaviour to the
* {@link AuthenticationSuccessHandler}.</li>
* </ol>
*
* Subclasses can override this method to continue the {@link FilterChain} after
@@ -331,13 +325,11 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* @throws IOException
* @throws ServletException
*/
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Authentication success. Updating SecurityContextHolder to contain: "
+ authResult);
logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
}
SecurityContextHolder.getContext().setAuthentication(authResult);
@@ -346,8 +338,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
// Fire event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
authResult, this.getClass()));
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
}
successHandler.onAuthenticationSuccess(request, response, authResult);
@@ -360,12 +351,12 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* <li>Stores the exception in the session (if it exists or
* <tt>allowSesssionCreation</tt> is set to <tt>true</tt>)</li>
* <li>Informs the configured <tt>RememberMeServices</tt> of the failed login</li>
* <li>Delegates additional behaviour to the {@link AuthenticationFailureHandler}.</li>
* <li>Delegates additional behaviour to the
* {@link AuthenticationFailureHandler}.</li>
* </ol>
*/
protected void unsuccessfulAuthentication(HttpServletRequest request,
HttpServletResponse response, AuthenticationException failed)
throws IOException, ServletException {
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
SecurityContextHolder.clearContext();
if (logger.isDebugEnabled()) {
@@ -389,16 +380,13 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
/**
* Sets the URL that determines if authentication is required
*
* @param filterProcessesUrl
*/
public void setFilterProcessesUrl(String filterProcessesUrl) {
setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(
filterProcessesUrl));
setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(filterProcessesUrl));
}
public final void setRequiresAuthenticationRequestMatcher(
RequestMatcher requestMatcher) {
public final void setRequiresAuthenticationRequestMatcher(RequestMatcher requestMatcher) {
Assert.notNull(requestMatcher, "requestMatcher cannot be null");
this.requiresAuthenticationRequestMatcher = requestMatcher;
}
@@ -418,8 +406,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* , which may be useful in certain environment (such as Tapestry applications).
* Defaults to <code>false</code>.
*/
public void setContinueChainBeforeSuccessfulAuthentication(
boolean continueChainBeforeSuccessfulAuthentication) {
public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
}
@@ -429,8 +416,7 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
@@ -451,12 +437,10 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* authentication request is successfully processed by the
* <tt>AuthenticationManager</tt>. Used, for example, to handle changing of the
* session identifier to prevent session fixation attacks.
*
* @param sessionStrategy the implementation to use. If not set a null implementation
* is used.
*/
public void setSessionAuthenticationStrategy(
SessionAuthenticationStrategy sessionStrategy) {
public void setSessionAuthenticationStrategy(SessionAuthenticationStrategy sessionStrategy) {
this.sessionStrategy = sessionStrategy;
}
@@ -464,14 +448,12 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
* Sets the strategy used to handle a successful authentication. By default a
* {@link SavedRequestAwareAuthenticationSuccessHandler} is used.
*/
public void setAuthenticationSuccessHandler(
AuthenticationSuccessHandler successHandler) {
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
Assert.notNull(successHandler, "successHandler cannot be null");
this.successHandler = successHandler;
}
public void setAuthenticationFailureHandler(
AuthenticationFailureHandler failureHandler) {
public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
Assert.notNull(failureHandler, "failureHandler cannot be null");
this.failureHandler = failureHandler;
}
@@ -483,4 +465,5 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
protected AuthenticationFailureHandler getFailureHandler() {
return failureHandler;
}
}
@@ -40,21 +40,17 @@ import org.springframework.util.StringUtils;
* Uses the following logic sequence to determine how it should handle the
* forward/redirect
* <ul>
* <li>
* If the {@code alwaysUseDefaultTargetUrl} property is set to true, the
* <li>If the {@code alwaysUseDefaultTargetUrl} property is set to true, the
* {@code defaultTargetUrl} property will be used for the destination.</li>
* <li>
* If a parameter matching the value of {@code targetUrlParameter} has been set on the
* <li>If a parameter matching the value of {@code targetUrlParameter} has been set on the
* request, the value will be used as the destination. If you are enabling this
* functionality, then you should ensure that the parameter cannot be used by an attacker
* to redirect the user to a malicious site (by clicking on a URL with the parameter
* included, for example). Typically it would be used when the parameter is included in
* the login form and submitted with the username and password.</li>
* <li>
* If the {@code useReferer} property is set, the "Referer" HTTP header value will be
* <li>If the {@code useReferer} property is set, the "Referer" HTTP header value will be
* used, if present.</li>
* <li>
* As a fallback option, the {@code defaultTargetUrl} value will be used.</li>
* <li>As a fallback option, the {@code defaultTargetUrl} value will be used.</li>
* </ul>
*
* @author Luke Taylor
@@ -63,10 +59,15 @@ import org.springframework.util.StringUtils;
public abstract class AbstractAuthenticationTargetUrlRequestHandler {
protected final Log logger = LogFactory.getLog(this.getClass());
private String targetUrlParameter = null;
private String defaultTargetUrl = "/";
private boolean alwaysUseDefaultTargetUrl = false;
private boolean useReferer = false;
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
protected AbstractAuthenticationTargetUrlRequestHandler() {
@@ -78,13 +79,12 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
* <p>
* The redirect will not be performed if the response has already been committed.
*/
protected void handle(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
String targetUrl = determineTargetUrl(request, response, authentication);
if (response.isCommitted()) {
logger.debug("Response has already been committed. Unable to redirect to "
+ targetUrl);
logger.debug("Response has already been committed. Unable to redirect to " + targetUrl);
return;
}
@@ -96,16 +96,15 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
*
* @since 5.2
*/
protected String determineTargetUrl(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) {
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
return determineTargetUrl(request, response);
}
/**
* Builds the target URL according to the logic defined in the main class Javadoc.
*/
protected String determineTargetUrl(HttpServletRequest request,
HttpServletResponse response) {
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response) {
if (isAlwaysUseDefaultTargetUrl()) {
return defaultTargetUrl;
}
@@ -140,7 +139,6 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
* Supplies the default target Url that will be used if no saved request is found or
* the {@code alwaysUseDefaultTargetUrl} property is set to true. If not set, defaults
* to {@code /}.
*
* @return the defaultTargetUrl property
*/
protected final String getDefaultTargetUrl() {
@@ -154,7 +152,6 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
* context path, and should include the leading <code>/</code>. Alternatively,
* inclusion of a scheme name (such as "http://" or "https://") as the prefix will
* denote a fully-qualified URL and this is also supported.
*
* @param defaultTargetUrl
*/
public void setDefaultTargetUrl(String defaultTargetUrl) {
@@ -178,7 +175,6 @@ public abstract class AbstractAuthenticationTargetUrlRequestHandler {
/**
* If this property is set, the current request will be checked for this a parameter
* with this name and the value used as the target URL if present.
*
* @param targetUrlParameter the name of the parameter containing the encoded target
* URL. Defaults to null.
*/
@@ -42,21 +42,22 @@ import org.springframework.web.filter.GenericFilterBean;
* @author Ben Alex
* @author Luke Taylor
*/
public class AnonymousAuthenticationFilter extends GenericFilterBean implements
InitializingBean {
public class AnonymousAuthenticationFilter extends GenericFilterBean implements InitializingBean {
// ~ Instance fields
// ================================================================================================
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
private String key;
private Object principal;
private List<GrantedAuthority> authorities;
/**
* Creates a filter with a principal named "anonymousUser" and the single authority
* "ROLE_ANONYMOUS".
*
* @param key the key to identify tokens created by this filter
*/
public AnonymousAuthenticationFilter(String key) {
@@ -64,13 +65,11 @@ public class AnonymousAuthenticationFilter extends GenericFilterBean implements
}
/**
*
* @param key key the key to identify tokens created by this filter
* @param principal the principal which will be used to represent anonymous users
* @param authorities the authority list for anonymous users
*/
public AnonymousAuthenticationFilter(String key, Object principal,
List<GrantedAuthority> authorities) {
public AnonymousAuthenticationFilter(String key, Object principal, List<GrantedAuthority> authorities) {
Assert.hasLength(key, "key cannot be null or empty");
Assert.notNull(principal, "Anonymous authentication principal must be set");
Assert.notNull(authorities, "Anonymous authorities must be set");
@@ -93,8 +92,7 @@ public class AnonymousAuthenticationFilter extends GenericFilterBean implements
throws IOException, ServletException {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
SecurityContextHolder.getContext().setAuthentication(
createAuthentication((HttpServletRequest) req));
SecurityContextHolder.getContext().setAuthentication(createAuthentication((HttpServletRequest) req));
if (logger.isDebugEnabled()) {
logger.debug("Populated SecurityContextHolder with anonymous token: '"
@@ -112,8 +110,7 @@ public class AnonymousAuthenticationFilter extends GenericFilterBean implements
}
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key,
principal, authorities);
AnonymousAuthenticationToken auth = new AnonymousAuthenticationToken(key, principal, authorities);
auth.setDetails(authenticationDetailsSource.buildDetails(request));
return auth;
@@ -121,8 +118,7 @@ public class AnonymousAuthenticationFilter extends GenericFilterBean implements
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
@@ -133,4 +129,5 @@ public class AnonymousAuthenticationFilter extends GenericFilterBean implements
public List<GrantedAuthority> getAuthorities() {
return authorities;
}
}
@@ -23,12 +23,11 @@ import org.springframework.security.core.AuthenticationException;
/**
* A strategy used for converting from a {@link HttpServletRequest} to an
* {@link Authentication} of particular type. Used to authenticate with
* appropriate {@link AuthenticationManager}. If the result is null, then it
* signals that no authentication attempt should be made. It is also possible to
* throw {@link AuthenticationException} within the
* {@link #convert(HttpServletRequest)} if there was invalid Authentication
* scheme value.
* {@link Authentication} of particular type. Used to authenticate with appropriate
* {@link AuthenticationManager}. If the result is null, then it signals that no
* authentication attempt should be made. It is also possible to throw
* {@link AuthenticationException} within the {@link #convert(HttpServletRequest)} if
* there was invalid Authentication scheme value.
*
* @author Sergey Bespalov
* @since 5.2.0
@@ -45,4 +45,5 @@ public class AuthenticationEntryPointFailureHandler implements AuthenticationFai
AuthenticationException exception) throws IOException, ServletException {
this.authenticationEntryPoint.commence(request, response, exception);
}
}
@@ -45,7 +45,7 @@ public interface AuthenticationFailureHandler {
* @param exception the exception which was thrown to reject the authentication
* request.
*/
void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException;
void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException;
}
@@ -36,26 +36,24 @@ import org.springframework.util.Assert;
import org.springframework.web.filter.OncePerRequestFilter;
/**
* A {@link Filter} that performs authentication of a particular request. An
* outline of the logic:
* A {@link Filter} that performs authentication of a particular request. An outline of
* the logic:
*
* <ul>
* <li>A request comes in and if it does not match
* {@link #setRequestMatcher(RequestMatcher)}, then this filter does nothing and
* the {@link FilterChain} is continued. If it does match then...</li>
* <li>An attempt to convert the {@link HttpServletRequest} into an
* {@link Authentication} is made. If the result is empty, then the filter does
* nothing more and the {@link FilterChain} is continued. If it does create an
* {@link Authentication}...</li>
* {@link #setRequestMatcher(RequestMatcher)}, then this filter does nothing and the
* {@link FilterChain} is continued. If it does match then...</li>
* <li>An attempt to convert the {@link HttpServletRequest} into an {@link Authentication}
* is made. If the result is empty, then the filter does nothing more and the
* {@link FilterChain} is continued. If it does create an {@link Authentication}...</li>
* <li>The {@link AuthenticationManager} specified in
* {@link #GenericAuthenticationFilter(AuthenticationManager)} is used to
* perform authentication.</li>
* <li>The {@link AuthenticationManagerResolver} specified in
* {@link #GenericAuthenticationFilter(AuthenticationManagerResolver)} is used
* to resolve the appropriate authentication manager from context to perform
* {@link #GenericAuthenticationFilter(AuthenticationManager)} is used to perform
* authentication.</li>
* <li>If authentication is successful, {@link AuthenticationSuccessHandler} is
* invoked and the authentication is set on {@link SecurityContextHolder}, else
* <li>The {@link AuthenticationManagerResolver} specified in
* {@link #GenericAuthenticationFilter(AuthenticationManagerResolver)} is used to resolve
* the appropriate authentication manager from context to perform authentication.</li>
* <li>If authentication is successful, {@link AuthenticationSuccessHandler} is invoked
* and the authentication is set on {@link SecurityContextHolder}, else
* {@link AuthenticationFailureHandler} is invoked</li>
* </ul>
*
@@ -65,10 +63,14 @@ import org.springframework.web.filter.OncePerRequestFilter;
public class AuthenticationFilter extends OncePerRequestFilter {
private RequestMatcher requestMatcher = AnyRequestMatcher.INSTANCE;
private AuthenticationConverter authenticationConverter;
private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
private AuthenticationFailureHandler failureHandler = new AuthenticationEntryPointFailureHandler(
new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));
private AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver;
public AuthenticationFilter(AuthenticationManager authenticationManager,
@@ -152,7 +154,8 @@ public class AuthenticationFilter extends OncePerRequestFilter {
}
successfulAuthentication(request, response, filterChain, authenticationResult);
} catch (AuthenticationException e) {
}
catch (AuthenticationException e) {
unsuccessfulAuthentication(request, response, e);
}
}
@@ -41,31 +41,28 @@ public interface AuthenticationSuccessHandler {
/**
* Called when a user has been successfully authenticated.
*
* @param request the request which caused the successful authentication
* @param response the response
* @param chain the {@link FilterChain} which can be used to proceed other filters in the chain
* @param chain the {@link FilterChain} which can be used to proceed other filters in
* the chain
* @param authentication the <tt>Authentication</tt> object which was created during
* the authentication process.
* @since 5.2.0
*/
default void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, FilterChain chain, Authentication authentication)
throws IOException, ServletException{
default void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authentication) throws IOException, ServletException {
onAuthenticationSuccess(request, response, authentication);
chain.doFilter(request, response);
}
/**
* Called when a user has been successfully authenticated.
*
* @param request the request which caused the successful authentication
* @param response the response
* @param authentication the <tt>Authentication</tt> object which was created during
* the authentication process.
*/
void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException;
void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
}
@@ -58,15 +58,15 @@ import org.springframework.util.Assert;
* @author Mike Wiesner
* @since 3.0.2
*/
public class DelegatingAuthenticationEntryPoint implements AuthenticationEntryPoint,
InitializingBean {
public class DelegatingAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean {
private final Log logger = LogFactory.getLog(getClass());
private final LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints;
private AuthenticationEntryPoint defaultEntryPoint;
public DelegatingAuthenticationEntryPoint(
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints) {
public DelegatingAuthenticationEntryPoint(LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints) {
this.entryPoints = entryPoints;
}
@@ -106,4 +106,5 @@ public class DelegatingAuthenticationEntryPoint implements AuthenticationEntryPo
Assert.notEmpty(entryPoints, "entryPoints must be specified");
Assert.notNull(defaultEntryPoint, "defaultEntryPoint must be specified");
}
}
@@ -35,8 +35,7 @@ import java.util.Map;
* @author Kazuki Shimizu
* @since 4.0
*/
public class DelegatingAuthenticationFailureHandler implements
AuthenticationFailureHandler {
public class DelegatingAuthenticationFailureHandler implements AuthenticationFailureHandler {
private final LinkedHashMap<Class<? extends AuthenticationException>, AuthenticationFailureHandler> handlers;
@@ -44,7 +43,6 @@ public class DelegatingAuthenticationFailureHandler implements
/**
* Creates a new instance
*
* @param handlers a map of the {@link AuthenticationException} class to the
* {@link AuthenticationFailureHandler} that should be used. Each is considered in the
* order they are specified and only the first {@link AuthenticationFailureHandler} is
@@ -66,13 +64,11 @@ public class DelegatingAuthenticationFailureHandler implements
* {@inheritDoc}
*/
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
for (Map.Entry<Class<? extends AuthenticationException>, AuthenticationFailureHandler> entry : handlers
.entrySet()) {
Class<? extends AuthenticationException> handlerMappedExceptionClass = entry
.getKey();
Class<? extends AuthenticationException> handlerMappedExceptionClass = entry.getKey();
if (handlerMappedExceptionClass.isAssignableFrom(exception.getClass())) {
AuthenticationFailureHandler handler = entry.getValue();
handler.onAuthenticationFailure(request, response, exception);
@@ -40,14 +40,13 @@ import org.springframework.util.Assert;
* @author Luke Taylor
* @since 3.0
*/
public class ExceptionMappingAuthenticationFailureHandler extends
SimpleUrlAuthenticationFailureHandler {
public class ExceptionMappingAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
private final Map<String, String> failureUrlMap = new HashMap<>();
@Override
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
String url = failureUrlMap.get(exception.getClass().getName());
if (url != null) {
@@ -60,10 +59,8 @@ public class ExceptionMappingAuthenticationFailureHandler extends
/**
* Sets the map of exception types (by name) to URLs.
*
* @param failureUrlMap the map keyed by the fully-qualified name of the exception
* class, with the corresponding failure URL as the value.
*
* @throws IllegalArgumentException if the entries are not Strings or the URL is not
* valid.
*/
@@ -72,12 +69,11 @@ public class ExceptionMappingAuthenticationFailureHandler extends
for (Map.Entry<?, ?> entry : failureUrlMap.entrySet()) {
Object exception = entry.getKey();
Object url = entry.getValue();
Assert.isInstanceOf(String.class, exception,
"Exception key must be a String (the exception classname).");
Assert.isInstanceOf(String.class, exception, "Exception key must be a String (the exception classname).");
Assert.isInstanceOf(String.class, url, "URL must be a String");
Assert.isTrue(UrlUtils.isValidRedirectUrl((String) url),
() -> "Not a valid redirect URL: " + url);
Assert.isTrue(UrlUtils.isValidRedirectUrl((String) url), () -> "Not a valid redirect URL: " + url);
this.failureUrlMap.put((String) exception, (String) url);
}
}
}
@@ -1,53 +1,54 @@
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* <p>
* Forward Authentication Failure Handler
* </p>
*
* @author Shazin Sadakath
* @since 4.1
*/
public class ForwardAuthenticationFailureHandler implements AuthenticationFailureHandler {
private final String forwardUrl;
/**
* @param forwardUrl
*/
public ForwardAuthenticationFailureHandler(String forwardUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl),
() -> "'" + forwardUrl + "' is not a valid forward URL");
this.forwardUrl = forwardUrl;
}
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
request.getRequestDispatcher(forwardUrl).forward(request, response);
}
}
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* <p>
* Forward Authentication Failure Handler
* </p>
*
* @author Shazin Sadakath
* @since 4.1
*/
public class ForwardAuthenticationFailureHandler implements AuthenticationFailureHandler {
private final String forwardUrl;
/**
* @param forwardUrl
*/
public ForwardAuthenticationFailureHandler(String forwardUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl), () -> "'" + forwardUrl + "' is not a valid forward URL");
this.forwardUrl = forwardUrl;
}
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
request.getRequestDispatcher(forwardUrl).forward(request, response);
}
}
@@ -1,52 +1,53 @@
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.authentication;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* <p>
* Forward Authentication Success Handler
* </p>
*
* @author Shazin Sadakath
* @since 4.1
*
*/
public class ForwardAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final String forwardUrl;
/**
* @param forwardUrl
*/
public ForwardAuthenticationSuccessHandler(String forwardUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl),
() -> "'" + forwardUrl + "' is not a valid forward URL");
this.forwardUrl = forwardUrl;
}
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
request.getRequestDispatcher(forwardUrl).forward(request, response);
}
}
/*
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.authentication;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* <p>
* Forward Authentication Success Handler
* </p>
*
* @author Shazin Sadakath
* @since 4.1
*
*/
public class ForwardAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final String forwardUrl;
/**
* @param forwardUrl
*/
public ForwardAuthenticationSuccessHandler(String forwardUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl), () -> "'" + forwardUrl + "' is not a valid forward URL");
this.forwardUrl = forwardUrl;
}
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
request.getRequestDispatcher(forwardUrl).forward(request, response);
}
}
@@ -39,22 +39,23 @@ import org.springframework.security.web.AuthenticationEntryPoint;
* <code>HttpServletResponse.SC_FORBIDDEN</code> (403 error).
*
* @see org.springframework.security.web.access.ExceptionTranslationFilter
*
* @author Luke Taylor
* @author Ruud Senden
* @since 2.0
*/
public class Http403ForbiddenEntryPoint implements AuthenticationEntryPoint {
private static final Log logger = LogFactory.getLog(Http403ForbiddenEntryPoint.class);
/**
* Always returns a 403 error code to the client.
*/
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException arg2) throws IOException {
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2)
throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-authenticated entry point called. Rejecting access");
}
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
}
}
@@ -32,11 +32,11 @@ import org.springframework.util.Assert;
* @since 4.0
*/
public final class HttpStatusEntryPoint implements AuthenticationEntryPoint {
private final HttpStatus httpStatus;
/**
* Creates a new instance.
*
* @param httpStatus the HttpStatus to set
*/
public HttpStatusEntryPoint(HttpStatus httpStatus) {
@@ -48,4 +48,5 @@ public final class HttpStatusEntryPoint implements AuthenticationEntryPoint {
AuthenticationException authException) {
response.setStatus(httpStatus.value());
}
}
@@ -62,13 +62,12 @@ import org.springframework.util.StringUtils;
* @author Luke Taylor
* @since 3.0
*/
public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoint,
InitializingBean {
public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean {
// ~ Static fields/initializers
// =====================================================================================
private static final Log logger = LogFactory
.getLog(LoginUrlAuthenticationEntryPoint.class);
private static final Log logger = LogFactory.getLog(LoginUrlAuthenticationEntryPoint.class);
// ~ Instance fields
// ================================================================================================
@@ -86,7 +85,6 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
/**
*
* @param loginFormUrl URL where the login page can be found. Should either be
* relative to the web-app context path (include a leading {@code /}) or an absolute
* URL.
@@ -100,13 +98,10 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
// ========================================================================================================
public void afterPropertiesSet() {
Assert.isTrue(
StringUtils.hasText(loginFormUrl)
&& UrlUtils.isValidRedirectUrl(loginFormUrl),
Assert.isTrue(StringUtils.hasText(loginFormUrl) && UrlUtils.isValidRedirectUrl(loginFormUrl),
"loginFormUrl must be specified and must be a valid redirect URL");
if (useForward && UrlUtils.isAbsoluteUrl(loginFormUrl)) {
throw new IllegalArgumentException(
"useForward must be false if using an absolute loginFormURL");
throw new IllegalArgumentException("useForward must be false if using an absolute loginFormURL");
}
Assert.notNull(portMapper, "portMapper must be specified");
Assert.notNull(portResolver, "portResolver must be specified");
@@ -115,14 +110,13 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
/**
* Allows subclasses to modify the login form URL that should be applicable for a
* given request.
*
* @param request the request
* @param response the response
* @param exception the exception
* @return the URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()})
*/
protected String determineUrlToUseForThisRequest(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception) {
protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) {
return getLoginFormUrl();
}
@@ -145,8 +139,7 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
}
if (redirectUrl == null) {
String loginForm = determineUrlToUseForThisRequest(request, response,
authException);
String loginForm = determineUrlToUseForThisRequest(request, response, authException);
if (logger.isDebugEnabled()) {
logger.debug("Server side forward to: " + loginForm);
@@ -169,11 +162,10 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
redirectStrategy.sendRedirect(request, response, redirectUrl);
}
protected String buildRedirectUrlToLoginPage(HttpServletRequest request,
HttpServletResponse response, AuthenticationException authException) {
protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) {
String loginForm = determineUrlToUseForThisRequest(request, response,
authException);
String loginForm = determineUrlToUseForThisRequest(request, response, authException);
if (UrlUtils.isAbsoluteUrl(loginForm)) {
return loginForm;
@@ -199,8 +191,7 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
urlBuilder.setPort(httpsPort);
}
else {
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port "
+ serverPort);
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
}
}
@@ -211,8 +202,7 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
* Builds a URL to redirect the supplied request to HTTPS. Used to redirect the
* current request to HTTPS, before doing a forward to the login page.
*/
protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
throws IOException, ServletException {
protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request) throws IOException, ServletException {
int serverPort = portResolver.getServerPort(request);
Integer httpsPort = portMapper.lookupHttpsPort(serverPort);
@@ -231,8 +221,7 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
}
// Fall through to server-side forward with warning message
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port "
+ serverPort);
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
return null;
}
@@ -277,7 +266,6 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
/**
* Tells if we are to do a forward to the {@code loginFormUrl} using the
* {@code RequestDispatcher}, instead of a 302 redirect.
*
* @param useForward true if a forward to the login page should be used. Must be false
* (the default) if {@code loginFormUrl} is set to an absolute value.
*/
@@ -288,4 +276,5 @@ public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoin
protected boolean isUseForward() {
return useForward;
}
}
@@ -30,11 +30,11 @@ import javax.servlet.http.HttpServletResponse;
* @author Ben Alex
*/
public class NullRememberMeServices implements RememberMeServices {
// ~ Methods
// ========================================================================================================
public Authentication autoLogin(HttpServletRequest request,
HttpServletResponse response) {
public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) {
return null;
}
@@ -44,4 +44,5 @@ public class NullRememberMeServices implements RememberMeServices {
public void loginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication) {
}
}
@@ -33,20 +33,21 @@ import org.springframework.security.core.Authentication;
* this interface.
* <p>
* Implementations may implement any type of remember-me capability they wish. Rolling
* cookies (as per <a
* href="https://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice">
* cookies (as per <a href=
* "https://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice">
* https://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice</a>) can
* be used, as can simple implementations that don't require a persistent store.
* Implementations also determine the validity period of a remember-me cookie. This
* interface has been designed to accommodate any of these remember-me models.
* <p>
* This interface does not define how remember-me services should offer a
* "cancel all remember-me tokens" type capability, as this will be implementation
* specific and requires no hooks into Spring Security.
* This interface does not define how remember-me services should offer a "cancel all
* remember-me tokens" type capability, as this will be implementation specific and
* requires no hooks into Spring Security.
*
* @author Ben Alex
*/
public interface RememberMeServices {
// ~ Methods
// ========================================================================================================
@@ -66,10 +67,8 @@ public interface RememberMeServices {
* by the web application. It is recommended
* {@link org.springframework.security.authentication.RememberMeAuthenticationToken}
* be used in most cases, as it has a corresponding authentication provider.
*
* @param request to look for a remember-me token within
* @param response to change, cancel or modify the remember-me token
*
* @return a valid authentication object, or <code>null</code> if the request should
* not be authenticated
*/
@@ -80,7 +79,6 @@ public interface RememberMeServices {
* supplied by the user were missing or otherwise invalid. Implementations should
* invalidate any and all remember-me tokens indicated in the
* <code>HttpServletRequest</code>.
*
* @param request that contained an invalid authentication request
* @param response to change, cancel or modify the remember-me token
*/
@@ -93,7 +91,6 @@ public interface RememberMeServices {
* implementations should typically look for a request parameter that indicates the
* browser has presented an explicit request for authentication to be remembered, such
* as the presence of a HTTP POST parameter.
*
* @param request that contained the valid authentication request
* @param response to change, cancel or modify the remember-me token
* @param successfulAuthentication representing the successfully authenticated
@@ -101,4 +98,5 @@ public interface RememberMeServices {
*/
void loginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication);
}
@@ -32,48 +32,45 @@ import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
/**
* An authentication success strategy which can make use of the
* {@link org.springframework.security.web.savedrequest.DefaultSavedRequest} which may have been stored in the session by the
* {@link ExceptionTranslationFilter}. When such a request is intercepted and requires
* authentication, the request data is stored to record the original destination before
* the authentication process commenced, and to allow the request to be reconstructed when
* a redirect to the same URL occurs. This class is responsible for performing the
* redirect to the original URL if appropriate.
* {@link org.springframework.security.web.savedrequest.DefaultSavedRequest} which may
* have been stored in the session by the {@link ExceptionTranslationFilter}. When such a
* request is intercepted and requires authentication, the request data is stored to
* record the original destination before the authentication process commenced, and to
* allow the request to be reconstructed when a redirect to the same URL occurs. This
* class is responsible for performing the redirect to the original URL if appropriate.
* <p>
* Following a successful authentication, it decides on the redirect destination, based on
* the following scenarios:
* <ul>
* <li>
* If the {@code alwaysUseDefaultTargetUrl} property is set to true, the
* <li>If the {@code alwaysUseDefaultTargetUrl} property is set to true, the
* {@code defaultTargetUrl} will be used for the destination. Any
* {@code DefaultSavedRequest} stored in the session will be removed.</li>
* <li>
* If the {@code targetUrlParameter} has been set on the request, the value will be used
* as the destination. Any {@code DefaultSavedRequest} will again be removed.</li>
* <li>
* If a {@link org.springframework.security.web.savedrequest.SavedRequest} is found in the {@code RequestCache} (as set by the
* {@link ExceptionTranslationFilter} to record the original destination before the
* authentication process commenced), a redirect will be performed to the Url of that
* original destination. The {@code SavedRequest} object will remain cached and be picked
* up when the redirected request is received (See
* <a href="{@docRoot}/org/springframework/security/web/savedrequest/SavedRequestAwareWrapper.html">SavedRequestAwareWrapper</a>).
* <li>If the {@code targetUrlParameter} has been set on the request, the value will be
* used as the destination. Any {@code DefaultSavedRequest} will again be removed.</li>
* <li>If a {@link org.springframework.security.web.savedrequest.SavedRequest} is found in
* the {@code RequestCache} (as set by the {@link ExceptionTranslationFilter} to record
* the original destination before the authentication process commenced), a redirect will
* be performed to the Url of that original destination. The {@code SavedRequest} object
* will remain cached and be picked up when the redirected request is received (See
* <a href="
* {@docRoot}/org/springframework/security/web/savedrequest/SavedRequestAwareWrapper.html">SavedRequestAwareWrapper</a>).
* </li>
* <li>
* If no {@link org.springframework.security.web.savedrequest.SavedRequest} is found, it will delegate to the base class.</li>
* <li>If no {@link org.springframework.security.web.savedrequest.SavedRequest} is found,
* it will delegate to the base class.</li>
* </ul>
*
* @author Luke Taylor
* @since 3.0
*/
public class SavedRequestAwareAuthenticationSuccessHandler extends
SimpleUrlAuthenticationSuccessHandler {
public class SavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
protected final Log logger = LogFactory.getLog(this.getClass());
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws ServletException, IOException {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
@@ -83,8 +80,7 @@ public class SavedRequestAwareAuthenticationSuccessHandler extends
}
String targetUrlParameter = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl()
|| (targetUrlParameter != null && StringUtils.hasText(request
.getParameter(targetUrlParameter)))) {
|| (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {
requestCache.removeRequest(request, response);
super.onAuthenticationSuccess(request, response, authentication);
@@ -102,4 +98,5 @@ public class SavedRequestAwareAuthenticationSuccessHandler extends
public void setRequestCache(RequestCache requestCache) {
this.requestCache = requestCache;
}
}
@@ -45,13 +45,16 @@ import org.springframework.util.Assert;
* @author Luke Taylor
* @since 3.0
*/
public class SimpleUrlAuthenticationFailureHandler implements
AuthenticationFailureHandler {
public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFailureHandler {
protected final Log logger = LogFactory.getLog(getClass());
private String defaultFailureUrl;
private boolean forwardToDestination = false;
private boolean allowSessionCreation = true;
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
public SimpleUrlAuthenticationFailureHandler() {
@@ -68,15 +71,13 @@ public class SimpleUrlAuthenticationFailureHandler implements
* If redirecting or forwarding, {@code saveException} will be called to cache the
* exception for use in the target view.
*/
public void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
if (defaultFailureUrl == null) {
logger.debug("No failure URL set, sending 401 Unauthorized error");
response.sendError(HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase());
response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
else {
saveException(request, exception);
@@ -84,8 +85,7 @@ public class SimpleUrlAuthenticationFailureHandler implements
if (forwardToDestination) {
logger.debug("Forwarding to " + defaultFailureUrl);
request.getRequestDispatcher(defaultFailureUrl)
.forward(request, response);
request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
}
else {
logger.debug("Redirecting to " + defaultFailureUrl);
@@ -102,8 +102,7 @@ public class SimpleUrlAuthenticationFailureHandler implements
* session and {@code allowSessionCreation} is {@code true} a session will be created.
* Otherwise the exception will not be stored.
*/
protected final void saveException(HttpServletRequest request,
AuthenticationException exception) {
protected final void saveException(HttpServletRequest request, AuthenticationException exception) {
if (forwardToDestination) {
request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
}
@@ -111,15 +110,13 @@ public class SimpleUrlAuthenticationFailureHandler implements
HttpSession session = request.getSession(false);
if (session != null || allowSessionCreation) {
request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION,
exception);
request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
}
}
}
/**
* The URL which will be used as the failure destination.
*
* @param defaultFailureUrl the failure URL, for example "/loginFailed.jsp".
*/
public void setDefaultFailureUrl(String defaultFailureUrl) {
@@ -158,4 +155,5 @@ public class SimpleUrlAuthenticationFailureHandler implements
public void setAllowSessionCreation(boolean allowSessionCreation) {
this.allowSessionCreation = allowSessionCreation;
}
}
@@ -35,9 +35,8 @@ import org.springframework.security.web.WebAttributes;
* @author Luke Taylor
* @since 3.0
*/
public class SimpleUrlAuthenticationSuccessHandler extends
AbstractAuthenticationTargetUrlRequestHandler implements
AuthenticationSuccessHandler {
public class SimpleUrlAuthenticationSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
implements AuthenticationSuccessHandler {
public SimpleUrlAuthenticationSuccessHandler() {
}
@@ -56,9 +55,8 @@ public class SimpleUrlAuthenticationSuccessHandler extends
* URL, and then calls {@code clearAuthenticationAttributes()} to remove any leftover
* session data.
*/
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
handle(request, response, authentication);
clearAuthenticationAttributes(request);
@@ -77,4 +75,5 @@ public class SimpleUrlAuthenticationSuccessHandler extends
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
}
@@ -45,18 +45,22 @@ import javax.servlet.http.HttpServletResponse;
* @author Luke Taylor
* @since 3.0
*/
public class UsernamePasswordAuthenticationFilter extends
AbstractAuthenticationProcessingFilter {
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
// ~ Static fields/initializers
// =====================================================================================
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER =
new AntPathRequestMatcher("/login", "POST");
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/login",
"POST");
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
private boolean postOnly = true;
// ~ Constructors
@@ -73,11 +77,10 @@ public class UsernamePasswordAuthenticationFilter extends
// ~ Methods
// ========================================================================================================
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
@@ -93,8 +96,7 @@ public class UsernamePasswordAuthenticationFilter extends
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
username, password);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
@@ -111,9 +113,7 @@ public class UsernamePasswordAuthenticationFilter extends
* password and extended value(s). The <code>AuthenticationDao</code> will need to
* generate the expected password in a corresponding manner.
* </p>
*
* @param request so that request attributes can be retrieved
*
* @return the password that will be presented in the <code>Authentication</code>
* request token to the <code>AuthenticationManager</code>
*/
@@ -125,9 +125,7 @@ public class UsernamePasswordAuthenticationFilter extends
/**
* Enables subclasses to override the composition of the username, such as by
* including additional values and a separator.
*
* @param request so that request attributes can be retrieved
*
* @return the username that will be presented in the <code>Authentication</code>
* request token to the <code>AuthenticationManager</code>
*/
@@ -139,20 +137,17 @@ public class UsernamePasswordAuthenticationFilter extends
/**
* Provided so that subclasses may configure what is put into the authentication
* request's details property.
*
* @param request that an authentication request is being created for
* @param authRequest the authentication request object that should have its details
* set
*/
protected void setDetails(HttpServletRequest request,
UsernamePasswordAuthenticationToken authRequest) {
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
/**
* Sets the parameter name which will be used to obtain the username from the login
* request.
*
* @param usernameParameter the parameter name. Defaults to "username".
*/
public void setUsernameParameter(String usernameParameter) {
@@ -163,7 +158,6 @@ public class UsernamePasswordAuthenticationFilter extends
/**
* Sets the parameter name which will be used to obtain the password from the login
* request..
*
* @param passwordParameter the parameter name. Defaults to "password".
*/
public void setPasswordParameter(String passwordParameter) {
@@ -191,4 +185,5 @@ public class UsernamePasswordAuthenticationFilter extends
public final String getPasswordParameter() {
return passwordParameter;
}
}
@@ -36,6 +36,7 @@ public class WebAuthenticationDetails implements Serializable {
// ================================================================================================
private final String remoteAddress;
private final String sessionId;
// ~ Constructors
@@ -44,7 +45,6 @@ public class WebAuthenticationDetails implements Serializable {
/**
* Records the remote address and will also set the session Id if a session already
* exists (it won't create one).
*
* @param request that the authentication request was received from
*/
public WebAuthenticationDetails(HttpServletRequest request) {
@@ -56,7 +56,6 @@ public class WebAuthenticationDetails implements Serializable {
/**
* Constructor to add Jackson2 serialize/deserialize support
*
* @param remoteAddress remote address of current request
* @param sessionId session id
*/
@@ -109,7 +108,6 @@ public class WebAuthenticationDetails implements Serializable {
/**
* Indicates the TCP/IP address the authentication request was received from.
*
* @return the address
*/
public String getRemoteAddress() {
@@ -119,7 +117,6 @@ public class WebAuthenticationDetails implements Serializable {
/**
* Indicates the <code>HttpSession</code> id the authentication request was received
* from.
*
* @return the session ID
*/
public String getSessionId() {
@@ -150,4 +147,5 @@ public class WebAuthenticationDetails implements Serializable {
return sb.toString();
}
}
@@ -27,8 +27,8 @@ import javax.servlet.http.HttpServletRequest;
*
* @author Ben Alex
*/
public class WebAuthenticationDetailsSource implements
AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
public class WebAuthenticationDetailsSource
implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
// ~ Methods
// ========================================================================================================
@@ -41,4 +41,5 @@ public class WebAuthenticationDetailsSource implements
public WebAuthenticationDetails buildDetails(HttpServletRequest context) {
return new WebAuthenticationDetails(context);
}
}
@@ -26,10 +26,10 @@ import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;
/**
* Performs a logout through all the {@link LogoutHandler} implementations.
* If any exception is thrown by
* {@link #logout(HttpServletRequest, HttpServletResponse, Authentication)},
* no additional LogoutHandler are invoked.
* Performs a logout through all the {@link LogoutHandler} implementations. If any
* exception is thrown by
* {@link #logout(HttpServletRequest, HttpServletResponse, Authentication)}, no additional
* LogoutHandler are invoked.
*
* @author Eddú Meléndez
* @since 4.2.0
@@ -54,4 +54,5 @@ public final class CompositeLogoutHandler implements LogoutHandler {
handler.logout(request, response, authentication);
}
}
}
@@ -26,16 +26,15 @@ import org.springframework.security.core.Authentication;
import org.springframework.util.Assert;
/**
* A logout handler which clears either
* - A defined list of cookie names, using the context path as the cookie path
* OR
* - A given list of Cookies
* A logout handler which clears either - A defined list of cookie names, using the
* context path as the cookie path OR - A given list of Cookies
*
* @author Luke Taylor
* @author Onur Kagan Ozcan
* @since 3.1
*/
public final class CookieClearingLogoutHandler implements LogoutHandler {
private final List<Function<HttpServletRequest, Cookie>> cookiesToClear;
public CookieClearingLogoutHandler(String... cookiesToClear) {
@@ -52,7 +51,7 @@ public final class CookieClearingLogoutHandler implements LogoutHandler {
};
cookieList.add(f);
}
this.cookiesToClear = cookieList;
this.cookiesToClear = cookieList;
}
/**
@@ -70,10 +69,8 @@ public final class CookieClearingLogoutHandler implements LogoutHandler {
this.cookiesToClear = cookieList;
}
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
cookiesToClear.forEach(
f -> response.addCookie(f.apply(request))
);
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
cookiesToClear.forEach(f -> response.addCookie(f.apply(request)));
}
}
@@ -1,77 +1,72 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.authentication.logout;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
/**
* Delegates to logout handlers based on matched request matchers
*
* @author Shazin Sadakath
* @author Rob Winch
* @since 4.1
*/
public class DelegatingLogoutSuccessHandler implements LogoutSuccessHandler {
private final LinkedHashMap<RequestMatcher, LogoutSuccessHandler> matcherToHandler;
private LogoutSuccessHandler defaultLogoutSuccessHandler;
public DelegatingLogoutSuccessHandler(
LinkedHashMap<RequestMatcher, LogoutSuccessHandler> matcherToHandler) {
Assert.notEmpty(matcherToHandler, "matcherToHandler cannot be null");
this.matcherToHandler = matcherToHandler;
}
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
for (Map.Entry<RequestMatcher, LogoutSuccessHandler> entry : this.matcherToHandler
.entrySet()) {
RequestMatcher matcher = entry.getKey();
if (matcher.matches(request)) {
LogoutSuccessHandler handler = entry.getValue();
handler.onLogoutSuccess(request, response, authentication);
return;
}
}
if (this.defaultLogoutSuccessHandler != null) {
this.defaultLogoutSuccessHandler.onLogoutSuccess(request, response,
authentication);
}
}
/**
* Sets the default {@link LogoutSuccessHandler} if no other handlers available
*
* @param defaultLogoutSuccessHandler the defaultLogoutSuccessHandler to set
*/
public void setDefaultLogoutSuccessHandler(
LogoutSuccessHandler defaultLogoutSuccessHandler) {
this.defaultLogoutSuccessHandler = defaultLogoutSuccessHandler;
}
}
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.web.authentication.logout;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
/**
* Delegates to logout handlers based on matched request matchers
*
* @author Shazin Sadakath
* @author Rob Winch
* @since 4.1
*/
public class DelegatingLogoutSuccessHandler implements LogoutSuccessHandler {
private final LinkedHashMap<RequestMatcher, LogoutSuccessHandler> matcherToHandler;
private LogoutSuccessHandler defaultLogoutSuccessHandler;
public DelegatingLogoutSuccessHandler(LinkedHashMap<RequestMatcher, LogoutSuccessHandler> matcherToHandler) {
Assert.notEmpty(matcherToHandler, "matcherToHandler cannot be null");
this.matcherToHandler = matcherToHandler;
}
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
for (Map.Entry<RequestMatcher, LogoutSuccessHandler> entry : this.matcherToHandler.entrySet()) {
RequestMatcher matcher = entry.getKey();
if (matcher.matches(request)) {
LogoutSuccessHandler handler = entry.getValue();
handler.onLogoutSuccess(request, response, authentication);
return;
}
}
if (this.defaultLogoutSuccessHandler != null) {
this.defaultLogoutSuccessHandler.onLogoutSuccess(request, response, authentication);
}
}
/**
* Sets the default {@link LogoutSuccessHandler} if no other handlers available
* @param defaultLogoutSuccessHandler the defaultLogoutSuccessHandler to set
*/
public void setDefaultLogoutSuccessHandler(LogoutSuccessHandler defaultLogoutSuccessHandler) {
this.defaultLogoutSuccessHandler = defaultLogoutSuccessHandler;
}
}
@@ -42,14 +42,13 @@ public class ForwardLogoutSuccessHandler implements LogoutSuccessHandler {
* @param targetUrl the target URL
*/
public ForwardLogoutSuccessHandler(String targetUrl) {
Assert.isTrue(UrlUtils.isValidRedirectUrl(targetUrl),
() -> "'" + targetUrl + "' is not a valid target URL");
Assert.isTrue(UrlUtils.isValidRedirectUrl(targetUrl), () -> "'" + targetUrl + "' is not a valid target URL");
this.targetUrl = targetUrl;
}
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
request.getRequestDispatcher(this.targetUrl).forward(request, response);
}
@@ -24,16 +24,15 @@ import org.springframework.security.web.header.HeaderWriter;
import org.springframework.util.Assert;
/**
*
* @author Rafiullah Hamedy
* @since 5.2
*/
public final class HeaderWriterLogoutHandler implements LogoutHandler {
private final HeaderWriter headerWriter;
/**
* Constructs a new instance using the passed {@link HeaderWriter} implementation
*
* @param headerWriter
* @throws {@link IllegalArgumentException} if headerWriter is null.
*/
@@ -43,8 +42,8 @@ public final class HeaderWriterLogoutHandler implements LogoutHandler {
}
@Override
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
this.headerWriter.writeHeaders(request, response);
}
}
@@ -40,7 +40,6 @@ public class HttpStatusReturningLogoutSuccessHandler implements LogoutSuccessHan
/**
* Initialize the {@code HttpStatusLogoutSuccessHandler} with a user-defined
* {@link HttpStatus}.
*
* @param httpStatusToReturn Must not be {@code null}.
*/
public HttpStatusReturningLogoutSuccessHandler(HttpStatus httpStatusToReturn) {
@@ -61,8 +60,8 @@ public class HttpStatusReturningLogoutSuccessHandler implements LogoutSuccessHan
* {@link LogoutSuccessHandler#onLogoutSuccess(HttpServletRequest, HttpServletResponse, Authentication)}
* . Sets the status on the {@link HttpServletResponse}.
*/
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
response.setStatus(this.httpStatusToReturn.value());
response.getWriter().flush();
}
@@ -57,6 +57,7 @@ public class LogoutFilter extends GenericFilterBean {
private RequestMatcher logoutRequestMatcher;
private final LogoutHandler handler;
private final LogoutSuccessHandler logoutSuccessHandler;
// ~ Constructors
@@ -68,8 +69,7 @@ public class LogoutFilter extends GenericFilterBean {
* intended to perform the actual logout functionality (such as clearing the security
* context, invalidating the session, etc.).
*/
public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler,
LogoutHandler... handlers) {
public LogoutFilter(LogoutSuccessHandler logoutSuccessHandler, LogoutHandler... handlers) {
this.handler = new CompositeLogoutHandler(handlers);
Assert.notNull(logoutSuccessHandler, "logoutSuccessHandler cannot be null");
this.logoutSuccessHandler = logoutSuccessHandler;
@@ -78,9 +78,7 @@ public class LogoutFilter extends GenericFilterBean {
public LogoutFilter(String logoutSuccessUrl, LogoutHandler... handlers) {
this.handler = new CompositeLogoutHandler(handlers);
Assert.isTrue(
!StringUtils.hasLength(logoutSuccessUrl)
|| UrlUtils.isValidRedirectUrl(logoutSuccessUrl),
Assert.isTrue(!StringUtils.hasLength(logoutSuccessUrl) || UrlUtils.isValidRedirectUrl(logoutSuccessUrl),
() -> logoutSuccessUrl + " isn't a valid redirect URL");
SimpleUrlLogoutSuccessHandler urlLogoutSuccessHandler = new SimpleUrlLogoutSuccessHandler();
if (StringUtils.hasText(logoutSuccessUrl)) {
@@ -102,8 +100,7 @@ public class LogoutFilter extends GenericFilterBean {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (logger.isDebugEnabled()) {
logger.debug("Logging out user '" + auth
+ "' and transferring to logout destination");
logger.debug("Logging out user '" + auth + "' and transferring to logout destination");
}
this.handler.logout(request, response, auth);
@@ -118,14 +115,11 @@ public class LogoutFilter extends GenericFilterBean {
/**
* Allow subclasses to modify when a logout should take place.
*
* @param request the request
* @param response the response
*
* @return <code>true</code> if logout should occur, <code>false</code> otherwise
*/
protected boolean requiresLogout(HttpServletRequest request,
HttpServletResponse response) {
protected boolean requiresLogout(HttpServletRequest request, HttpServletResponse response) {
return logoutRequestMatcher.matches(request);
}
@@ -137,4 +131,5 @@ public class LogoutFilter extends GenericFilterBean {
public void setFilterProcessesUrl(String filterProcessesUrl) {
this.logoutRequestMatcher = new AntPathRequestMatcher(filterProcessesUrl);
}
}
@@ -30,16 +30,16 @@ import javax.servlet.http.HttpServletResponse;
* @author Ben Alex
*/
public interface LogoutHandler {
// ~ Methods
// ========================================================================================================
/**
* Causes a logout to be completed. The method must complete successfully.
*
* @param request the HTTP request
* @param response the HTTP response
* @param authentication the current principal details
*/
void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication);
void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication);
}
@@ -36,7 +36,7 @@ import org.springframework.security.core.Authentication;
*/
public interface LogoutSuccessHandler {
void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException;
void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException;
}
@@ -41,9 +41,11 @@ import org.springframework.util.Assert;
* @author Rob Winch
*/
public class SecurityContextLogoutHandler implements LogoutHandler {
protected final Log logger = LogFactory.getLog(this.getClass());
private boolean invalidateHttpSession = true;
private boolean clearAuthentication = true;
// ~ Methods
@@ -51,13 +53,11 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
/**
* Requires the request to be passed in.
*
* @param request from which to obtain a HTTP session (cannot be null)
* @param response not used (can be <code>null</code>)
* @param authentication not used (can be <code>null</code>)
*/
public void logout(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) {
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
Assert.notNull(request, "HttpServletRequest required");
if (invalidateHttpSession) {
HttpSession session = request.getSession(false);
@@ -82,7 +82,6 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
/**
* Causes the {@link HttpSession} to be invalidated when this {@link LogoutHandler} is
* invoked. Defaults to true.
*
* @param invalidateHttpSession true if you wish the session to be invalidated
* (default) or false if it should not be.
*/
@@ -93,7 +92,6 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
/**
* If true, removes the {@link Authentication} from the {@link SecurityContext} to
* prevent issues with concurrent requests.
*
* @param clearAuthentication true if you wish to clear the {@link Authentication}
* from the {@link SecurityContext} (default) or false if the {@link Authentication}
* should not be removed.
@@ -101,4 +99,5 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
public void setClearAuthentication(boolean clearAuthentication) {
this.clearAuthentication = clearAuthentication;
}
}
@@ -31,11 +31,11 @@ import org.springframework.security.web.authentication.AbstractAuthenticationTar
* @author Luke Taylor
* @since 3.0
*/
public class SimpleUrlLogoutSuccessHandler extends
AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler {
public class SimpleUrlLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler
implements LogoutSuccessHandler {
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
super.handle(request, response, authentication);
}
@@ -17,4 +17,3 @@
* Logout functionality based around a filter which handles a specific logout URL.
*/
package org.springframework.security.web.authentication.logout;
@@ -18,4 +18,3 @@
* credentials using various protocols (eg BASIC, CAS, form login etc).
*/
package org.springframework.security.web.authentication;
@@ -81,13 +81,21 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
implements ApplicationEventPublisherAware {
private ApplicationEventPublisher eventPublisher = null;
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
private AuthenticationManager authenticationManager = null;
private boolean continueFilterChainOnUnsuccessfulAuthentication = true;
private boolean checkForPrincipalChanges;
private boolean invalidateSessionOnPrincipalChange = true;
private AuthenticationSuccessHandler authenticationSuccessHandler = null;
private AuthenticationFailureHandler authenticationFailureHandler = null;
private RequestMatcher requiresAuthenticationRequestMatcher = new PreAuthenticatedProcessingRequestMatcher();
/**
@@ -109,12 +117,11 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
* Try to authenticate a pre-authenticated user with Spring Security if the user has
* not yet been authenticated.
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Checking secure context token: "
+ SecurityContextHolder.getContext().getAuthentication());
logger.debug("Checking secure context token: " + SecurityContextHolder.getContext().getAuthentication());
}
if (requiresAuthenticationRequestMatcher.matches((HttpServletRequest) request)) {
@@ -128,14 +135,16 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
* Determines if the current principal has changed. The default implementation tries
*
* <ul>
* <li>If the {@link #getPreAuthenticatedPrincipal(HttpServletRequest)} is a String, the {@link Authentication#getName()} is compared against the pre authenticated principal</li>
* <li>Otherwise, the {@link #getPreAuthenticatedPrincipal(HttpServletRequest)} is compared against the {@link Authentication#getPrincipal()}
* <li>If the {@link #getPreAuthenticatedPrincipal(HttpServletRequest)} is a String,
* the {@link Authentication#getName()} is compared against the pre authenticated
* principal</li>
* <li>Otherwise, the {@link #getPreAuthenticatedPrincipal(HttpServletRequest)} is
* compared against the {@link Authentication#getPrincipal()}
* </ul>
*
* <p>
* Subclasses can override this method to determine when a principal has changed.
* </p>
*
* @param request
* @param currentAuthentication
* @return true if the principal has changed, else false
@@ -161,7 +170,8 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
/**
* Do the actual authentication for a pre-authenticated user.
*/
private void doAuthenticate(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
private void doAuthenticate(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
Authentication authResult;
Object principal = getPreAuthenticatedPrincipal(request);
@@ -176,13 +186,12 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
}
if (logger.isDebugEnabled()) {
logger.debug("preAuthenticatedPrincipal = " + principal
+ ", trying to authenticate");
logger.debug("preAuthenticatedPrincipal = " + principal + ", trying to authenticate");
}
try {
PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken(
principal, credentials);
PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken(principal,
credentials);
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
authResult = authenticationManager.authenticate(authRequest);
successfulAuthentication(request, response, authResult);
@@ -200,16 +209,15 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
* Puts the <code>Authentication</code> instance returned by the authentication
* manager into the secure context.
*/
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response, Authentication authResult) throws IOException, ServletException {
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
Authentication authResult) throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Authentication success: " + authResult);
}
SecurityContextHolder.getContext().setAuthentication(authResult);
// Fire event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
authResult, this.getClass()));
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
}
if (authenticationSuccessHandler != null) {
@@ -223,8 +231,8 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
* <p>
* Caches the failure exception as a request attribute
*/
protected void unsuccessfulAuthentication(HttpServletRequest request,
HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
SecurityContextHolder.clearContext();
if (logger.isDebugEnabled()) {
@@ -240,8 +248,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
/**
* @param anApplicationEventPublisher The ApplicationEventPublisher to use
*/
public void setApplicationEventPublisher(
ApplicationEventPublisher anApplicationEventPublisher) {
public void setApplicationEventPublisher(ApplicationEventPublisher anApplicationEventPublisher) {
this.eventPublisher = anApplicationEventPublisher;
}
@@ -250,8 +257,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
*/
public void setAuthenticationDetailsSource(
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
Assert.notNull(authenticationDetailsSource,
"AuthenticationDetailsSource required");
Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
this.authenticationDetailsSource = authenticationDetailsSource;
}
@@ -267,11 +273,10 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
}
/**
* If set to {@code true} (the default), any {@code AuthenticationException} raised by the
* {@code AuthenticationManager} will be swallowed, and the request will be allowed to
* proceed, potentially using alternative authentication mechanisms. If {@code false},
* authentication failure will result in an immediate exception.
*
* If set to {@code true} (the default), any {@code AuthenticationException} raised by
* the {@code AuthenticationManager} will be swallowed, and the request will be
* allowed to proceed, potentially using alternative authentication mechanisms. If
* {@code false}, authentication failure will result in an immediate exception.
* @param shouldContinue set to {@code true} to allow the request to proceed after a
* failed authentication.
*/
@@ -284,7 +289,6 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
* compared against the name of the current <tt>Authentication</tt> object. A check to
* determine if {@link Authentication#getPrincipal()} is equal to the principal will
* also be performed. If a change is detected, the user will be reauthenticated.
*
* @param checkForPrincipalChanges
*/
public void setCheckForPrincipalChanges(boolean checkForPrincipalChanges) {
@@ -295,12 +299,10 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
* If <tt>checkForPrincipalChanges</tt> is set, and a change of principal is detected,
* determines whether any existing session should be invalidated before proceeding to
* authenticate the new principal.
*
* @param invalidateSessionOnPrincipalChange <tt>false</tt> to retain the existing
* session. Defaults to <tt>true</tt>.
*/
public void setInvalidateSessionOnPrincipalChange(
boolean invalidateSessionOnPrincipalChange) {
public void setInvalidateSessionOnPrincipalChange(boolean invalidateSessionOnPrincipalChange) {
this.invalidateSessionOnPrincipalChange = invalidateSessionOnPrincipalChange;
}
@@ -44,13 +44,14 @@ import org.springframework.util.Assert;
* @author Ruud Senden
* @since 2.0
*/
public class PreAuthenticatedAuthenticationProvider implements AuthenticationProvider,
InitializingBean, Ordered {
private static final Log logger = LogFactory
.getLog(PreAuthenticatedAuthenticationProvider.class);
public class PreAuthenticatedAuthenticationProvider implements AuthenticationProvider, InitializingBean, Ordered {
private static final Log logger = LogFactory.getLog(PreAuthenticatedAuthenticationProvider.class);
private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> preAuthenticatedUserDetailsService = null;
private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
private boolean throwExceptionWhenTokenRejected = false;
private int order = -1; // default: same as non-ordered
@@ -59,8 +60,7 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
* Check whether all required properties have been set.
*/
public void afterPropertiesSet() {
Assert.notNull(preAuthenticatedUserDetailsService,
"An AuthenticationUserDetailsService must be set");
Assert.notNull(preAuthenticatedUserDetailsService, "An AuthenticationUserDetailsService must be set");
}
/**
@@ -69,8 +69,7 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
* If the principal contained in the authentication object is null, the request will
* be ignored to allow other providers to authenticate it.
*/
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (!supports(authentication.getClass())) {
return null;
}
@@ -83,8 +82,7 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
logger.debug("No pre-authenticated principal found in request.");
if (throwExceptionWhenTokenRejected) {
throw new BadCredentialsException(
"No pre-authenticated principal found in request.");
throw new BadCredentialsException("No pre-authenticated principal found in request.");
}
return null;
}
@@ -93,8 +91,7 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
logger.debug("No pre-authenticated credentials found in request.");
if (throwExceptionWhenTokenRejected) {
throw new BadCredentialsException(
"No pre-authenticated credentials found in request.");
throw new BadCredentialsException("No pre-authenticated credentials found in request.");
}
return null;
}
@@ -104,8 +101,8 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
userDetailsChecker.check(ud);
PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(
ud, authentication.getCredentials(), ud.getAuthorities());
PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(ud,
authentication.getCredentials(), ud.getAuthorities());
result.setDetails(authentication.getDetails());
return result;
@@ -122,7 +119,6 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
/**
* Set the AuthenticatedUserDetailsService to be used to load the {@code UserDetails}
* for the authenticated user.
*
* @param uds
*/
public void setPreAuthenticatedUserDetailsService(
@@ -156,4 +152,5 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
public void setOrder(int i) {
order = i;
}
}
@@ -33,13 +33,13 @@ public class PreAuthenticatedAuthenticationToken extends AbstractAuthenticationT
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final Object principal;
private final Object credentials;
/**
* Constructor used for an authentication request. The
* {@link org.springframework.security.core.Authentication#isAuthenticated()} will
* return <code>false</code>.
*
* @param aPrincipal The pre-authenticated principal
* @param aCredentials The pre-authenticated credentials
*/
@@ -53,7 +53,6 @@ public class PreAuthenticatedAuthenticationToken extends AbstractAuthenticationT
* Constructor used for an authentication response. The
* {@link org.springframework.security.core.Authentication#isAuthenticated()} will
* return <code>true</code>.
*
* @param aPrincipal The authenticated principal
* @param anAuthorities The granted authorities
*/
@@ -24,11 +24,11 @@ public class PreAuthenticatedCredentialsNotFoundException extends Authentication
}
/**
*
* @param message The message for the Exception
* @param cause The Exception that caused this Exception.
*/
public PreAuthenticatedCredentialsNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
@@ -45,31 +45,30 @@ import org.springframework.util.Assert;
* @author Ruud Senden
* @since 2.0
*/
public class PreAuthenticatedGrantedAuthoritiesUserDetailsService implements
AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
public class PreAuthenticatedGrantedAuthoritiesUserDetailsService
implements AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> {
/**
* Get a UserDetails object based on the user name contained in the given token, and
* the GrantedAuthorities as returned by the GrantedAuthoritiesContainer
* implementation as returned by the token.getDetails() method.
*/
public final UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
throws AuthenticationException {
public final UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws AuthenticationException {
Assert.notNull(token.getDetails(), "token.getDetails() cannot be null");
Assert.isInstanceOf(GrantedAuthoritiesContainer.class, token.getDetails());
Collection<? extends GrantedAuthority> authorities = ((GrantedAuthoritiesContainer) token
.getDetails()).getGrantedAuthorities();
Collection<? extends GrantedAuthority> authorities = ((GrantedAuthoritiesContainer) token.getDetails())
.getGrantedAuthorities();
return createUserDetails(token, authorities);
}
/**
* Creates the final <tt>UserDetails</tt> object. Can be overridden to customize the
* contents.
*
* @param token the authentication request token
* @param authorities the pre-authenticated authorities.
*/
protected UserDetails createUserDetails(Authentication token,
Collection<? extends GrantedAuthority> authorities) {
protected UserDetails createUserDetails(Authentication token, Collection<? extends GrantedAuthority> authorities) {
return new User(token.getName(), "N/A", true, true, true, true, authorities);
}
}
@@ -31,15 +31,15 @@ import java.util.*;
* @author Luke Taylor
* @since 2.0
*/
public class PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails extends
WebAuthenticationDetails implements GrantedAuthoritiesContainer {
public class PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails extends WebAuthenticationDetails
implements GrantedAuthoritiesContainer {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final List<GrantedAuthority> authorities;
public PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(
HttpServletRequest request, Collection<? extends GrantedAuthority> authorities) {
public PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(HttpServletRequest request,
Collection<? extends GrantedAuthority> authorities) {
super(request);
List<GrantedAuthority> temp = new ArrayList<>(authorities.size());
@@ -59,4 +59,5 @@ public class PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails extends
sb.append(authorities);
return sb.toString();
}
}
@@ -22,8 +22,9 @@ import org.springframework.util.Assert;
/**
* A simple pre-authenticated filter which obtains the username from request attributes,
* for use with SSO systems such as
* <a href="https://webauth.stanford.edu/manual/mod/mod_webauth.html#java">Stanford WebAuth</a> or
* <a href="https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPJavaInstall">Shibboleth</a>.
* <a href="https://webauth.stanford.edu/manual/mod/mod_webauth.html#java">Stanford
* WebAuth</a> or <a href=
* "https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPJavaInstall">Shibboleth</a>.
* <p>
* As with most pre-authenticated scenarios, it is essential that the external
* authentication system is set up correctly as this filter does no authentication
@@ -37,20 +38,20 @@ import org.springframework.util.Assert;
* {@code getPreAuthenticatedPrincipal} will throw an exception. You can override this
* behaviour by setting the {@code exceptionIfVariableMissing} property.
*
*
* @author Milan Sevcik
* @since 4.2
*/
public class RequestAttributeAuthenticationFilter
extends AbstractPreAuthenticatedProcessingFilter {
public class RequestAttributeAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
private String principalEnvironmentVariable = "REMOTE_USER";
private String credentialsEnvironmentVariable;
private boolean exceptionIfVariableMissing = true;
/**
* Read and returns the variable named by {@code principalEnvironmentVariable} from
* the request.
*
* @throws PreAuthenticatedCredentialsNotFoundException if the environment variable is
* missing and {@code exceptionIfVariableMissing} is set to {@code true}.
*/
@@ -79,25 +80,23 @@ public class RequestAttributeAuthenticationFilter
}
public void setPrincipalEnvironmentVariable(String principalEnvironmentVariable) {
Assert.hasText(principalEnvironmentVariable,
"principalEnvironmentVariable must not be empty or null");
Assert.hasText(principalEnvironmentVariable, "principalEnvironmentVariable must not be empty or null");
this.principalEnvironmentVariable = principalEnvironmentVariable;
}
public void setCredentialsEnvironmentVariable(String credentialsEnvironmentVariable) {
Assert.hasText(credentialsEnvironmentVariable,
"credentialsEnvironmentVariable must not be empty or null");
Assert.hasText(credentialsEnvironmentVariable, "credentialsEnvironmentVariable must not be empty or null");
this.credentialsEnvironmentVariable = credentialsEnvironmentVariable;
}
/**
* Defines whether an exception should be raised if the principal variable is missing.
* Defaults to {@code true}.
*
* @param exceptionIfVariableMissing set to {@code false} to override the default
* behaviour and allow the request to proceed if no variable is found.
*/
public void setExceptionIfVariableMissing(boolean exceptionIfVariableMissing) {
this.exceptionIfVariableMissing = exceptionIfVariableMissing;
}
}
@@ -39,20 +39,20 @@ import org.springframework.util.Assert;
* throw an exception. You can override this behaviour by setting the
* {@code exceptionIfHeaderMissing} property.
*
*
* @author Luke Taylor
* @since 2.0
*/
public class RequestHeaderAuthenticationFilter extends
AbstractPreAuthenticatedProcessingFilter {
public class RequestHeaderAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
private String principalRequestHeader = "SM_USER";
private String credentialsRequestHeader;
private boolean exceptionIfHeaderMissing = true;
/**
* Read and returns the header named by {@code principalRequestHeader} from the
* request.
*
* @throws PreAuthenticatedCredentialsNotFoundException if the header is missing and
* {@code exceptionIfHeaderMissing} is set to {@code true}.
*/
@@ -60,8 +60,8 @@ public class RequestHeaderAuthenticationFilter extends
String principal = request.getHeader(principalRequestHeader);
if (principal == null && exceptionIfHeaderMissing) {
throw new PreAuthenticatedCredentialsNotFoundException(principalRequestHeader
+ " header not found in request.");
throw new PreAuthenticatedCredentialsNotFoundException(
principalRequestHeader + " header not found in request.");
}
return principal;
@@ -81,25 +81,23 @@ public class RequestHeaderAuthenticationFilter extends
}
public void setPrincipalRequestHeader(String principalRequestHeader) {
Assert.hasText(principalRequestHeader,
"principalRequestHeader must not be empty or null");
Assert.hasText(principalRequestHeader, "principalRequestHeader must not be empty or null");
this.principalRequestHeader = principalRequestHeader;
}
public void setCredentialsRequestHeader(String credentialsRequestHeader) {
Assert.hasText(credentialsRequestHeader,
"credentialsRequestHeader must not be empty or null");
Assert.hasText(credentialsRequestHeader, "credentialsRequestHeader must not be empty or null");
this.credentialsRequestHeader = credentialsRequestHeader;
}
/**
* Defines whether an exception should be raised if the principal header is missing.
* Defaults to {@code true}.
*
* @param exceptionIfHeaderMissing set to {@code false} to override the default
* behaviour and allow the request to proceed if no header is found.
*/
public void setExceptionIfHeaderMissing(boolean exceptionIfHeaderMissing) {
this.exceptionIfHeaderMissing = exceptionIfHeaderMissing;
}
}
@@ -37,14 +37,17 @@ import java.util.*;
* @author Ruud Senden
* @since 2.0
*/
public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
implements
public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource implements
AuthenticationDetailsSource<HttpServletRequest, PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails>,
InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
/** The role attributes returned by the configured {@code MappableAttributesRetriever} */
/**
* The role attributes returned by the configured {@code MappableAttributesRetriever}
*/
protected Set<String> j2eeMappableRoles;
protected Attributes2GrantedAuthoritiesMapper j2eeUserRoles2GrantedAuthoritiesMapper = new SimpleAttributes2GrantedAuthoritiesMapper();
/**
@@ -52,8 +55,7 @@ public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
*/
public void afterPropertiesSet() {
Assert.notNull(j2eeMappableRoles, "No mappable roles available");
Assert.notNull(j2eeUserRoles2GrantedAuthoritiesMapper,
"Roles to granted authorities mapper not set");
Assert.notNull(j2eeUserRoles2GrantedAuthoritiesMapper, "Roles to granted authorities mapper not set");
}
/**
@@ -61,7 +63,6 @@ public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
* {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)} method is called
* for each of the values in the {@code j2eeMappableRoles} set to determine if that
* role should be assigned to the user.
*
* @param request the request which should be used to extract the user's roles.
* @return The subset of {@code j2eeMappableRoles} which applies to the current user
* making the request.
@@ -83,16 +84,14 @@ public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
*
* @see org.springframework.security.authentication.AuthenticationDetailsSource#buildDetails(Object)
*/
public PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails buildDetails(
HttpServletRequest context) {
public PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails buildDetails(HttpServletRequest context) {
Collection<String> j2eeUserRoles = getUserRoles(context);
Collection<? extends GrantedAuthority> userGas = j2eeUserRoles2GrantedAuthoritiesMapper
.getGrantedAuthorities(j2eeUserRoles);
if (logger.isDebugEnabled()) {
logger.debug("J2EE roles [" + j2eeUserRoles
+ "] mapped to Granted Authorities: [" + userGas + "]");
logger.debug("J2EE roles [" + j2eeUserRoles + "] mapped to Granted Authorities: [" + userGas + "]");
}
PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails result = new PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(
@@ -104,17 +103,15 @@ public class J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource
/**
* @param aJ2eeMappableRolesRetriever The MappableAttributesRetriever to use
*/
public void setMappableRolesRetriever(
MappableAttributesRetriever aJ2eeMappableRolesRetriever) {
this.j2eeMappableRoles = Collections.unmodifiableSet(aJ2eeMappableRolesRetriever
.getMappableAttributes());
public void setMappableRolesRetriever(MappableAttributesRetriever aJ2eeMappableRolesRetriever) {
this.j2eeMappableRoles = Collections.unmodifiableSet(aJ2eeMappableRolesRetriever.getMappableAttributes());
}
/**
* @param mapper The Attributes2GrantedAuthoritiesMapper to use
*/
public void setUserRoles2GrantedAuthoritiesMapper(
Attributes2GrantedAuthoritiesMapper mapper) {
public void setUserRoles2GrantedAuthoritiesMapper(Attributes2GrantedAuthoritiesMapper mapper) {
j2eeUserRoles2GrantedAuthoritiesMapper = mapper;
}
}
@@ -27,15 +27,13 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen
* @author Ruud Senden
* @since 2.0
*/
public class J2eePreAuthenticatedProcessingFilter extends
AbstractPreAuthenticatedProcessingFilter {
public class J2eePreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {
/**
* Return the J2EE user name.
*/
protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpRequest) {
Object principal = httpRequest.getUserPrincipal() == null ? null : httpRequest
.getUserPrincipal().getName();
Object principal = httpRequest.getUserPrincipal() == null ? null : httpRequest.getUserPrincipal().getName();
if (logger.isDebugEnabled()) {
logger.debug("PreAuthenticated J2EE principal: " + principal);
}
@@ -49,4 +47,5 @@ public class J2eePreAuthenticatedProcessingFilter extends
protected Object getPreAuthenticatedCredentials(HttpServletRequest httpRequest) {
return "N/A";
}
}
@@ -51,11 +51,13 @@ import org.xml.sax.SAXException;
* @author Luke Taylor
* @since 2.0
*/
public class WebXmlMappableAttributesRetriever implements ResourceLoaderAware,
MappableAttributesRetriever, InitializingBean {
public class WebXmlMappableAttributesRetriever
implements ResourceLoaderAware, MappableAttributesRetriever, InitializingBean {
protected final Log logger = LogFactory.getLog(getClass());
private ResourceLoader resourceLoader;
private Set<String> mappableAttributes;
public void setResourceLoader(ResourceLoader resourceLoader) {
@@ -76,11 +78,9 @@ public class WebXmlMappableAttributesRetriever implements ResourceLoaderAware,
Document doc = getDocument(webXml.getInputStream());
NodeList webApp = doc.getElementsByTagName("web-app");
if (webApp.getLength() != 1) {
throw new IllegalArgumentException(
"Failed to find 'web-app' element in resource" + webXml);
throw new IllegalArgumentException("Failed to find 'web-app' element in resource" + webXml);
}
NodeList securityRoles = ((Element) webApp.item(0))
.getElementsByTagName("security-role");
NodeList securityRoles = ((Element) webApp.item(0)).getElementsByTagName("security-role");
ArrayList<String> roleNames = new ArrayList<>();
@@ -116,7 +116,8 @@ public class WebXmlMappableAttributesRetriever implements ResourceLoaderAware,
}
catch (FactoryConfigurationError | IOException | SAXException | ParserConfigurationException e) {
throw new RuntimeException("Unable to parse document object", e);
} finally {
}
finally {
try {
aStream.close();
}
@@ -130,8 +131,11 @@ public class WebXmlMappableAttributesRetriever implements ResourceLoaderAware,
* We do not need to resolve external entities, so just return an empty String.
*/
private static final class MyEntityResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) {
return new InputSource(new StringReader(""));
}
}
}
@@ -16,8 +16,8 @@
/**
* Pre-authentication support for container-authenticated requests.
* <p>
* It is assumed that standard JEE security has been configured and Spring Security hooks into the
* security methods exposed by {@code HttpServletRequest} to build {@code Authentication} object for the user.
* It is assumed that standard JEE security has been configured and Spring Security hooks
* into the security methods exposed by {@code HttpServletRequest} to build
* {@code Authentication} object for the user.
*/
package org.springframework.security.web.authentication.preauth.j2ee;
@@ -14,8 +14,7 @@
* limitations under the License.
*/
/**
* Support for "pre-authenticated" scenarios, where Spring Security assumes the incoming request has already been
* authenticated by some externally configured system.
* Support for "pre-authenticated" scenarios, where Spring Security assumes the incoming
* request has already been authenticated by some externally configured system.
*/
package org.springframework.security.web.authentication.preauth;
@@ -40,8 +40,8 @@ import org.apache.commons.logging.LogFactory;
* @since 2.0
*/
final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroupsExtractor {
private static final Log logger = LogFactory
.getLog(DefaultWASUsernameAndGroupsExtractor.class);
private static final Log logger = LogFactory.getLog(DefaultWASUsernameAndGroupsExtractor.class);
private static final String PORTABLE_REMOTE_OBJECT_CLASSNAME = "javax.rmi.PortableRemoteObject";
@@ -68,7 +68,6 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
/**
* Get the security name for the given subject.
*
* @param subject The subject for which to retrieve the security name
* @return String the security name for the given subject
*/
@@ -79,23 +78,19 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
String userSecurityName = null;
if (subject != null) {
// SEC-803
Object credential = subject.getPublicCredentials(getWSCredentialClass())
.iterator().next();
Object credential = subject.getPublicCredentials(getWSCredentialClass()).iterator().next();
if (credential != null) {
userSecurityName = (String) invokeMethod(getSecurityNameMethod(),
credential);
userSecurityName = (String) invokeMethod(getSecurityNameMethod(), credential);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Websphere security name is " + userSecurityName
+ " for subject " + subject);
logger.debug("Websphere security name is " + userSecurityName + " for subject " + subject);
}
return userSecurityName;
}
/**
* Get the current RunAs subject.
*
* @return Subject the current RunAs subject
*/
private static Subject getRunAsSubject() {
@@ -106,7 +101,6 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
/**
* Get the WebSphere group names for the given subject.
*
* @param subject The subject for which to retrieve the WebSphere group names
* @return the WebSphere group names for the given subject
*/
@@ -116,7 +110,6 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
/**
* Get the WebSphere group names for the given security name.
*
* @param securityName The security name for which to retrieve the WebSphere group
* names
* @return the WebSphere group names for the given security name
@@ -128,13 +121,14 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
// TODO: Cache UserRegistry object
ic = new InitialContext();
Object objRef = ic.lookup(USER_REGISTRY);
Object userReg = invokeMethod(getNarrowMethod(), null , objRef, Class.forName("com.ibm.websphere.security.UserRegistry"));
Object userReg = invokeMethod(getNarrowMethod(), null, objRef,
Class.forName("com.ibm.websphere.security.UserRegistry"));
if (logger.isDebugEnabled()) {
logger.debug("Determining WebSphere groups for user " + securityName
+ " using WebSphere UserRegistry " + userReg);
logger.debug("Determining WebSphere groups for user " + securityName + " using WebSphere UserRegistry "
+ userReg);
}
final Collection groups = (Collection) invokeMethod(getGroupsForUserMethod(),
userReg, new Object[] { securityName });
final Collection groups = (Collection) invokeMethod(getGroupsForUserMethod(), userReg,
new Object[] { securityName });
if (logger.isDebugEnabled()) {
logger.debug("Groups for user " + securityName + ": " + groups.toString());
}
@@ -143,8 +137,7 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
}
catch (Exception e) {
logger.error("Exception occured while looking up groups for user", e);
throw new RuntimeException(
"Exception occured while looking up groups for user", e);
throw new RuntimeException("Exception occured while looking up groups for user", e);
}
finally {
try {
@@ -163,30 +156,26 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
return method.invoke(instance, args);
}
catch (IllegalArgumentException e) {
logger.error("Error while invoking method " + method.getClass().getName()
+ "." + method.getName() + "(" + Arrays.asList(args) + ")", e);
throw new RuntimeException("Error while invoking method "
+ method.getClass().getName() + "." + method.getName() + "("
logger.error("Error while invoking method " + method.getClass().getName() + "." + method.getName() + "("
+ Arrays.asList(args) + ")", e);
throw new RuntimeException("Error while invoking method " + method.getClass().getName() + "."
+ method.getName() + "(" + Arrays.asList(args) + ")", e);
}
catch (IllegalAccessException e) {
logger.error("Error while invoking method " + method.getClass().getName()
+ "." + method.getName() + "(" + Arrays.asList(args) + ")", e);
throw new RuntimeException("Error while invoking method "
+ method.getClass().getName() + "." + method.getName() + "("
logger.error("Error while invoking method " + method.getClass().getName() + "." + method.getName() + "("
+ Arrays.asList(args) + ")", e);
throw new RuntimeException("Error while invoking method " + method.getClass().getName() + "."
+ method.getName() + "(" + Arrays.asList(args) + ")", e);
}
catch (InvocationTargetException e) {
logger.error("Error while invoking method " + method.getClass().getName()
+ "." + method.getName() + "(" + Arrays.asList(args) + ")", e);
throw new RuntimeException("Error while invoking method "
+ method.getClass().getName() + "." + method.getName() + "("
logger.error("Error while invoking method " + method.getClass().getName() + "." + method.getName() + "("
+ Arrays.asList(args) + ")", e);
throw new RuntimeException("Error while invoking method " + method.getClass().getName() + "."
+ method.getName() + "(" + Arrays.asList(args) + ")", e);
}
}
private static Method getMethod(String className, String methodName,
String[] parameterTypeNames) {
private static Method getMethod(String className, String methodName, String[] parameterTypeNames) {
try {
Class<?> c = Class.forName(className);
final int len = parameterTypeNames.length;
@@ -201,40 +190,40 @@ final class DefaultWASUsernameAndGroupsExtractor implements WASUsernameAndGroups
throw new RuntimeException("Required class" + className + " not found", e);
}
catch (NoSuchMethodException e) {
logger.error("Required method " + methodName + " with parameter types ("
+ Arrays.asList(parameterTypeNames) + ") not found on class "
+ className);
logger.error("Required method " + methodName + " with parameter types (" + Arrays.asList(parameterTypeNames)
+ ") not found on class " + className);
throw new RuntimeException("Required class" + className + " not found", e);
}
}
private static Method getRunAsSubjectMethod() {
if (getRunAsSubject == null) {
getRunAsSubject = getMethod("com.ibm.websphere.security.auth.WSSubject",
"getRunAsSubject", new String[] {});
getRunAsSubject = getMethod("com.ibm.websphere.security.auth.WSSubject", "getRunAsSubject",
new String[] {});
}
return getRunAsSubject;
}
private static Method getGroupsForUserMethod() {
if (getGroupsForUser == null) {
getGroupsForUser = getMethod("com.ibm.websphere.security.UserRegistry",
"getGroupsForUser", new String[] { "java.lang.String" });
getGroupsForUser = getMethod("com.ibm.websphere.security.UserRegistry", "getGroupsForUser",
new String[] { "java.lang.String" });
}
return getGroupsForUser;
}
private static Method getSecurityNameMethod() {
if (getSecurityName == null) {
getSecurityName = getMethod("com.ibm.websphere.security.cred.WSCredential",
"getSecurityName", new String[] {});
getSecurityName = getMethod("com.ibm.websphere.security.cred.WSCredential", "getSecurityName",
new String[] {});
}
return getSecurityName;
}
private static Method getNarrowMethod() {
if (narrow == null) {
narrow = getMethod(PORTABLE_REMOTE_OBJECT_CLASSNAME, "narrow", new String[] { Object.class.getName() , Class.class.getName()});
narrow = getMethod(PORTABLE_REMOTE_OBJECT_CLASSNAME, "narrow",
new String[] { Object.class.getName(), Class.class.getName() });
}
return narrow;
}
@@ -31,4 +31,5 @@ interface WASUsernameAndGroupsExtractor {
List<String> getGroupsForCurrentUser();
String getCurrentUserName();
}
@@ -27,8 +27,8 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen
* @author Ruud Senden
* @since 2.0
*/
public class WebSpherePreAuthenticatedProcessingFilter extends
AbstractPreAuthenticatedProcessingFilter {
public class WebSpherePreAuthenticatedProcessingFilter extends AbstractPreAuthenticatedProcessingFilter {
private final WASUsernameAndGroupsExtractor wasHelper;
/**
@@ -62,4 +62,5 @@ public class WebSpherePreAuthenticatedProcessingFilter extends
protected Object getPreAuthenticatedCredentials(HttpServletRequest httpRequest) {
return "N/A";
}
}
@@ -33,9 +33,9 @@ import java.util.*;
*
* @author Ruud Senden
*/
public class WebSpherePreAuthenticatedWebAuthenticationDetailsSource
implements
public class WebSpherePreAuthenticatedWebAuthenticationDetailsSource implements
AuthenticationDetailsSource<HttpServletRequest, PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails> {
private final Log logger = LogFactory.getLog(getClass());
private Attributes2GrantedAuthoritiesMapper webSphereGroups2GrantedAuthoritiesMapper = new SimpleAttributes2GrantedAuthoritiesMapper();
@@ -46,20 +46,17 @@ public class WebSpherePreAuthenticatedWebAuthenticationDetailsSource
this(new DefaultWASUsernameAndGroupsExtractor());
}
public WebSpherePreAuthenticatedWebAuthenticationDetailsSource(
WASUsernameAndGroupsExtractor wasHelper) {
public WebSpherePreAuthenticatedWebAuthenticationDetailsSource(WASUsernameAndGroupsExtractor wasHelper) {
this.wasHelper = wasHelper;
}
public PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails buildDetails(
HttpServletRequest context) {
public PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails buildDetails(HttpServletRequest context) {
return new PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails(context,
getWebSphereGroupsBasedGrantedAuthorities());
}
/**
* Get a list of Granted Authorities based on the current user's WebSphere groups.
*
* @return authorities mapped from the user's WebSphere groups.
*/
private Collection<? extends GrantedAuthority> getWebSphereGroupsBasedGrantedAuthorities() {
@@ -67,8 +64,7 @@ public class WebSpherePreAuthenticatedWebAuthenticationDetailsSource
Collection<? extends GrantedAuthority> userGas = webSphereGroups2GrantedAuthoritiesMapper
.getGrantedAuthorities(webSphereGroups);
if (logger.isDebugEnabled()) {
logger.debug("WebSphere groups: " + webSphereGroups
+ " mapped to Granted Authorities: " + userGas);
logger.debug("WebSphere groups: " + webSphereGroups + " mapped to Granted Authorities: " + userGas);
}
return userGas;
}
@@ -77,8 +73,7 @@ public class WebSpherePreAuthenticatedWebAuthenticationDetailsSource
* @param mapper The Attributes2GrantedAuthoritiesMapper to use for converting the WAS
* groups to authorities
*/
public void setWebSphereGroups2GrantedAuthoritiesMapper(
Attributes2GrantedAuthoritiesMapper mapper) {
public void setWebSphereGroups2GrantedAuthoritiesMapper(Attributes2GrantedAuthoritiesMapper mapper) {
webSphereGroups2GrantedAuthoritiesMapper = mapper;
}
@@ -17,4 +17,3 @@
* Websphere-specific pre-authentication classes.
*/
package org.springframework.security.web.authentication.preauth.websphere;

Some files were not shown because too many files have changed in this diff Show More