1
0
mirror of synced 2026-08-05 09:47:05 +00:00

Add SecurityContextHolderStrategy to Pre-authenticated scenarios

Issue gh-11060
Issue gh-11061
This commit is contained in:
Josh Cummings
2022-06-21 16:42:16 -06:00
parent b3be35da31
commit 98995f2225
8 changed files with 179 additions and 17 deletions
@@ -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");