|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright 2002-2021 the original author or authors.
|
|
|
+ * Copyright 2002-2022 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.
|
|
@@ -36,6 +36,7 @@ import org.springframework.security.core.Authentication;
|
|
|
import org.springframework.security.core.AuthenticationException;
|
|
|
import org.springframework.security.core.context.SecurityContext;
|
|
|
import org.springframework.security.core.context.SecurityContextHolder;
|
|
|
+import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
|
|
import org.springframework.security.web.WebAttributes;
|
|
|
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
|
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
|
@@ -88,6 +89,9 @@ import org.springframework.web.filter.GenericFilterBean;
|
|
|
public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFilterBean
|
|
|
implements ApplicationEventPublisherAware {
|
|
|
|
|
|
+ private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
|
|
+ .getContextHolderStrategy();
|
|
|
+
|
|
|
private ApplicationEventPublisher eventPublisher = null;
|
|
|
|
|
|
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
|
@@ -132,8 +136,8 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|
|
throws IOException, ServletException {
|
|
|
if (this.requiresAuthenticationRequestMatcher.matches((HttpServletRequest) request)) {
|
|
|
if (logger.isDebugEnabled()) {
|
|
|
- logger.debug(LogMessage
|
|
|
- .of(() -> "Authenticating " + SecurityContextHolder.getContext().getAuthentication()));
|
|
|
+ logger.debug(LogMessage.of(
|
|
|
+ () -> "Authenticating " + this.securityContextHolderStrategy.getContext().getAuthentication()));
|
|
|
}
|
|
|
doAuthenticate((HttpServletRequest) request, (HttpServletResponse) response);
|
|
|
}
|
|
@@ -211,9 +215,9 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|
|
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
|
|
Authentication authResult) throws IOException, ServletException {
|
|
|
this.logger.debug(LogMessage.format("Authentication success: %s", authResult));
|
|
|
- SecurityContext context = SecurityContextHolder.createEmptyContext();
|
|
|
+ SecurityContext context = this.securityContextHolderStrategy.createEmptyContext();
|
|
|
context.setAuthentication(authResult);
|
|
|
- SecurityContextHolder.setContext(context);
|
|
|
+ this.securityContextHolderStrategy.setContext(context);
|
|
|
this.securityContextRepository.saveContext(context, request, response);
|
|
|
if (this.eventPublisher != null) {
|
|
|
this.eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
|
|
@@ -231,7 +235,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|
|
*/
|
|
|
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
|
|
AuthenticationException failed) throws IOException, ServletException {
|
|
|
- SecurityContextHolder.clearContext();
|
|
|
+ this.securityContextHolderStrategy.clearContext();
|
|
|
this.logger.debug("Cleared security context due to exception", failed);
|
|
|
request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, failed);
|
|
|
if (this.authenticationFailureHandler != null) {
|
|
@@ -335,6 +339,17 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|
|
this.requiresAuthenticationRequestMatcher = requiresAuthenticationRequestMatcher;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Sets the {@link SecurityContextHolderStrategy} to use. The default action is to use
|
|
|
+ * the {@link SecurityContextHolderStrategy} stored in {@link SecurityContextHolder}.
|
|
|
+ *
|
|
|
+ * @since 5.8
|
|
|
+ */
|
|
|
+ public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
|
|
|
+ Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
|
|
|
+ this.securityContextHolderStrategy = securityContextHolderStrategy;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Override to extract the principal information from the current request
|
|
|
*/
|
|
@@ -354,7 +369,8 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|
|
|
|
|
@Override
|
|
|
public boolean matches(HttpServletRequest request) {
|
|
|
- Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
|
|
|
+ Authentication currentUser = AbstractPreAuthenticatedProcessingFilter.this.securityContextHolderStrategy
|
|
|
+ .getContext().getAuthentication();
|
|
|
if (currentUser == null) {
|
|
|
return true;
|
|
|
}
|
|
@@ -367,7 +383,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
|
|
|
AbstractPreAuthenticatedProcessingFilter.this.logger
|
|
|
.debug("Pre-authenticated principal has changed and will be reauthenticated");
|
|
|
if (AbstractPreAuthenticatedProcessingFilter.this.invalidateSessionOnPrincipalChange) {
|
|
|
- SecurityContextHolder.clearContext();
|
|
|
+ AbstractPreAuthenticatedProcessingFilter.this.securityContextHolderStrategy.clearContext();
|
|
|
HttpSession session = request.getSession(false);
|
|
|
if (session != null) {
|
|
|
AbstractPreAuthenticatedProcessingFilter.this.logger.debug("Invalidating existing session");
|