spring-attic / spring-security-oauth

Support for adding OAuth1(a) and OAuth2 features (consumer and provider) for Spring web applications.
http://github.com/spring-projects/spring-security-oauth
Apache License 2.0
4.69k stars 4.04k forks source link

Security Context Holder returning different users in token when running in an async context #1511

Open imduffy15 opened 5 years ago

imduffy15 commented 5 years ago

Hi,

I have the following controller:

@Controller
public class Endpoint {

  public Endpoint() {
  }

  public CompletableFuture<ResponseEntity<Void>> func() {
    return CompletableFuture.supplyAsync(() -> {

      System.out.println(new DefaultOAuth2AccessToken(
        ((OAuth2AuthenticationDetails)
          SecurityContextHolder.getContext().getAuthentication().getDetails())
          .getTokenValue()).getValue());

      return new ResponseEntity<>(HttpStatus.OK);
    });
  }
}

I have configured spring to use MODE_INHERITABLETHREADLOCAL with the following bean:

  @Bean
  public MethodInvokingFactoryBean methodInvokingFactoryBean() {
    MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
    methodInvokingFactoryBean.setTargetClass(SecurityContextHolder.class);
    methodInvokingFactoryBean.setTargetMethod("setStrategyName");
    methodInvokingFactoryBean.setArguments(new String[]{SecurityContextHolder.MODE_INHERITABLETHREADLOCAL});
    return methodInvokingFactoryBean;
  }

If a request comes in with auth token "abc" the print statement above will print "abc" correctly. However, if a new request comes in with a different token "abc" is still printed.

vishalksahu commented 3 years ago

Do we have a solution yet?

ghost commented 3 years ago

It looks that when the MODE_INHERITABLETHREADLOCAL set the security context in the threads of a ForkJoinPool when a thread ends his job does not clean the context, so when a thread is used again sometimes it has the context of a different request.