Browse Source

Address SecurityContextHolder memory leak

To get current context without creating a new context.
Creating a new context may cause ThreadLocal leak.

Closes gh-9841
pull/10574/head
Hiroshi Shirosaki 5 years ago committed by Josh Cummings
parent
commit
2bc643d6c8
  1. 14
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/SecurityReactorContextConfiguration.java
  2. 5
      core/src/main/java/org/springframework/security/core/context/GlobalSecurityContextHolderStrategy.java
  3. 5
      core/src/main/java/org/springframework/security/core/context/InheritableThreadLocalSecurityContextHolderStrategy.java
  4. 8
      core/src/main/java/org/springframework/security/core/context/SecurityContextHolder.java
  5. 6
      core/src/main/java/org/springframework/security/core/context/SecurityContextHolderStrategy.java
  6. 5
      core/src/main/java/org/springframework/security/core/context/ThreadLocalSecurityContextHolderStrategy.java

14
config/src/main/java/org/springframework/security/config/annotation/web/configuration/SecurityReactorContextConfiguration.java

@ -36,6 +36,7 @@ import org.springframework.beans.factory.InitializingBean; @@ -36,6 +36,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
@ -94,7 +95,12 @@ class SecurityReactorContextConfiguration { @@ -94,7 +95,12 @@ class SecurityReactorContextConfiguration {
}
private static boolean contextAttributesAvailable() {
return SecurityContextHolder.getContext().getAuthentication() != null
SecurityContext context = SecurityContextHolder.peekContext();
Authentication authentication = null;
if (context != null) {
authentication = context.getAuthentication();
}
return authentication != null
|| RequestContextHolder.getRequestAttributes() instanceof ServletRequestAttributes;
}
@ -107,7 +113,11 @@ class SecurityReactorContextConfiguration { @@ -107,7 +113,11 @@ class SecurityReactorContextConfiguration {
servletRequest = servletRequestAttributes.getRequest();
servletResponse = servletRequestAttributes.getResponse(); // possible null
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
SecurityContext context = SecurityContextHolder.peekContext();
Authentication authentication = null;
if (context != null) {
authentication = context.getAuthentication();
}
if (authentication == null && servletRequest == null) {
return Collections.emptyMap();
}

5
core/src/main/java/org/springframework/security/core/context/GlobalSecurityContextHolderStrategy.java

@ -44,6 +44,11 @@ final class GlobalSecurityContextHolderStrategy implements SecurityContextHolder @@ -44,6 +44,11 @@ final class GlobalSecurityContextHolderStrategy implements SecurityContextHolder
return contextHolder;
}
@Override
public SecurityContext peekContext() {
return contextHolder;
}
@Override
public void setContext(SecurityContext context) {
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");

5
core/src/main/java/org/springframework/security/core/context/InheritableThreadLocalSecurityContextHolderStrategy.java

@ -44,6 +44,11 @@ final class InheritableThreadLocalSecurityContextHolderStrategy implements Secur @@ -44,6 +44,11 @@ final class InheritableThreadLocalSecurityContextHolderStrategy implements Secur
return ctx;
}
@Override
public SecurityContext peekContext() {
return contextHolder.get();
}
@Override
public void setContext(SecurityContext context) {
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");

8
core/src/main/java/org/springframework/security/core/context/SecurityContextHolder.java

@ -123,6 +123,14 @@ public class SecurityContextHolder { @@ -123,6 +123,14 @@ public class SecurityContextHolder {
return strategy.getContext();
}
/**
* Peeks the current <code>SecurityContext</code>.
* @return the security context (may be <code>null</code>)
*/
public static SecurityContext peekContext() {
return strategy.peekContext();
}
/**
* Primarily for troubleshooting purposes, this method shows how many times the class
* has re-initialized its <code>SecurityContextHolderStrategy</code>.

6
core/src/main/java/org/springframework/security/core/context/SecurityContextHolderStrategy.java

@ -38,6 +38,12 @@ public interface SecurityContextHolderStrategy { @@ -38,6 +38,12 @@ public interface SecurityContextHolderStrategy {
*/
SecurityContext getContext();
/**
* Peeks the current context without creating an empty context.
* @return a context (may be <code>null</code>)
*/
SecurityContext peekContext();
/**
* Sets the current context.
* @param context to the new argument (should never be <code>null</code>, although

5
core/src/main/java/org/springframework/security/core/context/ThreadLocalSecurityContextHolderStrategy.java

@ -45,6 +45,11 @@ final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextH @@ -45,6 +45,11 @@ final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextH
return ctx;
}
@Override
public SecurityContext peekContext() {
return contextHolder.get();
}
@Override
public void setContext(SecurityContext context) {
Assert.notNull(context, "Only non-null SecurityContext instances are permitted");

Loading…
Cancel
Save