소스 검색

Polish SecurityContextHolderStrategy for Defaults

gh-11060
Josh Cummings 3 년 전
부모
커밋
a7b58c2299

+ 17 - 2
web/src/main/java/org/springframework/security/web/authentication/logout/SecurityContextLogoutHandler.java

@@ -26,6 +26,7 @@ import org.springframework.core.log.LogMessage;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.util.Assert;
 
 /**
@@ -45,6 +46,9 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
 
 	protected final Log logger = LogFactory.getLog(this.getClass());
 
+	private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
+			.getContextHolderStrategy();
+
 	private boolean invalidateHttpSession = true;
 
 	private boolean clearAuthentication = true;
@@ -67,8 +71,8 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
 				}
 			}
 		}
-		SecurityContext context = SecurityContextHolder.getContext();
-		SecurityContextHolder.clearContext();
+		SecurityContext context = this.securityContextHolderStrategy.getContext();
+		this.securityContextHolderStrategy.clearContext();
 		if (this.clearAuthentication) {
 			context.setAuthentication(null);
 		}
@@ -78,6 +82,17 @@ public class SecurityContextLogoutHandler implements LogoutHandler {
 		return this.invalidateHttpSession;
 	}
 
+	/**
+	 * 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;
+	}
+
 	/**
 	 * Causes the {@link HttpSession} to be invalidated when this {@link LogoutHandler} is
 	 * invoked. Defaults to true.

+ 1 - 1
web/src/main/java/org/springframework/security/web/method/annotation/AuthenticationPrincipalArgumentResolver.java

@@ -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.

+ 17 - 2
web/src/main/java/org/springframework/security/web/method/annotation/CurrentSecurityContextArgumentResolver.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 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.
@@ -28,6 +28,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
 import org.springframework.security.core.annotation.CurrentSecurityContext;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.stereotype.Controller;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
@@ -75,6 +76,9 @@ import org.springframework.web.method.support.ModelAndViewContainer;
  */
 public final class CurrentSecurityContextArgumentResolver implements HandlerMethodArgumentResolver {
 
+	private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
+			.getContextHolderStrategy();
+
 	private ExpressionParser parser = new SpelExpressionParser();
 
 	private BeanResolver beanResolver;
@@ -87,7 +91,7 @@ public final class CurrentSecurityContextArgumentResolver implements HandlerMeth
 	@Override
 	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
 			NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
-		SecurityContext securityContext = SecurityContextHolder.getContext();
+		SecurityContext securityContext = this.securityContextHolderStrategy.getContext();
 		if (securityContext == null) {
 			return null;
 		}
@@ -113,6 +117,17 @@ public final class CurrentSecurityContextArgumentResolver implements HandlerMeth
 		return securityContextResult;
 	}
 
+	/**
+	 * 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;
+	}
+
 	/**
 	 * Set the {@link BeanResolver} to be used on the expressions
 	 * @param beanResolver the {@link BeanResolver} to use

+ 19 - 5
web/src/main/java/org/springframework/security/web/servletapi/HttpServlet3RequestFactory.java

@@ -41,6 +41,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.AuthenticationEntryPoint;
 import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
 import org.springframework.security.web.authentication.logout.LogoutHandler;
@@ -76,6 +77,9 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
 
 	private Log logger = LogFactory.getLog(getClass());
 
+	private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
+			.getContextHolderStrategy();
+
 	private final String rolePrefix;
 
 	private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
@@ -161,9 +165,17 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
 		this.trustResolver = trustResolver;
 	}
 
+	void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
+		Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
+		this.securityContextHolderStrategy = securityContextHolderStrategy;
+	}
+
 	@Override
 	public HttpServletRequest create(HttpServletRequest request, HttpServletResponse response) {
-		return new Servlet3SecurityContextHolderAwareRequestWrapper(request, this.rolePrefix, response);
+		Servlet3SecurityContextHolderAwareRequestWrapper wrapper = new Servlet3SecurityContextHolderAwareRequestWrapper(
+				request, this.rolePrefix, response);
+		wrapper.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
+		return wrapper;
 	}
 
 	private class Servlet3SecurityContextHolderAwareRequestWrapper extends SecurityContextHolderAwareRequestWrapper {
@@ -228,9 +240,10 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
 				return;
 			}
 			Authentication authentication = getAuthentication(authManager, username, password);
-			SecurityContext context = SecurityContextHolder.createEmptyContext();
+			SecurityContext context = HttpServlet3RequestFactory.this.securityContextHolderStrategy
+					.createEmptyContext();
 			context.setAuthentication(authentication);
-			SecurityContextHolder.setContext(context);
+			HttpServlet3RequestFactory.this.securityContextHolderStrategy.setContext(context);
 		}
 
 		private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)
@@ -243,7 +256,7 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
 				return authManager.authenticate(authentication);
 			}
 			catch (AuthenticationException ex) {
-				SecurityContextHolder.clearContext();
+				HttpServlet3RequestFactory.this.securityContextHolderStrategy.clearContext();
 				throw new ServletException(ex.getMessage(), ex);
 			}
 		}
@@ -257,7 +270,8 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
 				super.logout();
 				return;
 			}
-			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+			Authentication authentication = HttpServlet3RequestFactory.this.securityContextHolderStrategy.getContext()
+					.getAuthentication();
 			for (LogoutHandler handler : handlers) {
 				handler.logout(this, this.response, authentication);
 			}

+ 16 - 0
web/src/main/java/org/springframework/security/web/servletapi/SecurityContextHolderAwareRequestFilter.java

@@ -32,6 +32,7 @@ import org.springframework.security.authentication.AuthenticationTrustResolver;
 import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
 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.AuthenticationEntryPoint;
 import org.springframework.security.web.authentication.logout.LogoutHandler;
 import org.springframework.util.Assert;
@@ -68,6 +69,9 @@ import org.springframework.web.filter.GenericFilterBean;
  */
 public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
 
+	private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
+			.getContextHolderStrategy();
+
 	private String rolePrefix = "ROLE_";
 
 	private HttpServletRequestFactory requestFactory;
@@ -80,6 +84,17 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
 
 	private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
 
+	/**
+	 * 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;
+	}
+
 	public void setRolePrefix(String rolePrefix) {
 		Assert.notNull(rolePrefix, "Role prefix must not be null");
 		this.rolePrefix = rolePrefix;
@@ -178,6 +193,7 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
 		factory.setAuthenticationEntryPoint(this.authenticationEntryPoint);
 		factory.setAuthenticationManager(this.authenticationManager);
 		factory.setLogoutHandlers(this.logoutHandlers);
+		factory.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
 		return factory;
 	}
 

+ 16 - 1
web/src/main/java/org/springframework/security/web/servletapi/SecurityContextHolderAwareRequestWrapper.java

@@ -28,6 +28,7 @@ import org.springframework.security.authentication.AuthenticationTrustResolverIm
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.context.SecurityContextHolderStrategy;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.util.Assert;
 
@@ -50,6 +51,9 @@ import org.springframework.util.Assert;
  */
 public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequestWrapper {
 
+	private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
+			.getContextHolderStrategy();
+
 	private final AuthenticationTrustResolver trustResolver;
 
 	/**
@@ -88,7 +92,7 @@ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequest
 	 * @return the authentication object or <code>null</code>
 	 */
 	private Authentication getAuthentication() {
-		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+		Authentication auth = this.securityContextHolderStrategy.getContext().getAuthentication();
 		return (!this.trustResolver.isAnonymous(auth)) ? auth : null;
 	}
 
@@ -169,4 +173,15 @@ public class SecurityContextHolderAwareRequestWrapper extends HttpServletRequest
 		return "SecurityContextHolderAwareRequestWrapper[ " + getRequest() + "]";
 	}
 
+	/**
+	 * 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;
+	}
+
 }