title: Error creating bean with name 'scopedTarget.oauth2ClientContext' despite defining RequestContextListener
body: <p>My app has multiple spring security configurations and one of them happens to be <code>Oauth2</code> (using <a href="https://github.com/OKaluzny/spring-boot-security-oauth2-google" rel="nofollow noreferrer">this</a> eaxmple).</p>
  
  <p><strong>Spring security in general is getting plugged in via:</strong></p>
  
  <pre><code>ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);             
  context.addFilter(GzipFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
  context.addFilter(new FilterHolder( new DelegatingFilterProxy( DEFAULT_FILTER_NAME ) ), "/*",EnumSet.allOf( DispatcherType.class ));
  AnnotationConfigWebApplicationContext securityContext = new AnnotationConfigWebApplicationContext();
  securityContext.setConfigLocation("com.test.auth");
  DispatcherServlet dispatcherServlet = new DispatcherServlet(securityContext);
  context.addServlet(new ServletHolder(dispatcherServlet), "/");
  context.addServlet(new ServletHolder(new ServletContainer(createResourceConfig(AuthController.class))), "/auth/*");
  </code></pre>
  
  <p><strong>Oauth2 which looks like this:</strong></p>
  
  <pre><code>@Order(4)
  @EnableOAuth2Client
  @EnableWebSecurity
  @Configuration  
  public class Oauth2Config extends WebSecurityConfigurerAdapter {    
          @Bean
          @Order(0)
          public RequestContextListener requestContextListener() {
              return new RequestContextListener();
          }
  
          @Autowired
          private OAuth2ClientContext oauth2ClientContext;
  
          @Autowired
          private OAuth2ClientContextFilter oauth2ClientContextFilter;
  
          @Autowired
          private AuthConfig authConfig;
  
          private OAuth2ProtectedResourceDetails authorizationCodeResource() {
              AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
  
              details.setId("google-oauth-client");
              details.setClientId(authConfig.getProperty("oauth2.clientId"));
              details.setClientSecret(authConfig.getProperty("oauth2.clientSecret"));
              details.setUserAuthorizationUri(authConfig.getProperty("oauth2.userAuthorizationUri"));
              details.setAccessTokenUri(authConfig.getProperty("oauth2.accessTokenUri"));
              details.setTokenName(authConfig.getProperty("oauth2.tokenName"));
              details.setScope(Arrays.asList(authConfig.getPropertyList("oauth2.scope")));
  
              details.setAuthenticationScheme(AuthenticationScheme.query);
              details.setClientAuthenticationScheme(AuthenticationScheme.form);
              return details;
          }     
  
  
  
          @Bean
          public OAuth2ClientAuthenticationProcessingFilter
                      oauth2ClientAuthenticationProcessingFilter() {
              // Used to obtain access token from authorization server (AS)
              OAuth2RestOperations restTemplate = new OAuth2RestTemplate(
                      authorizationCodeResource(),
                      oauth2ClientContext);
              OAuth2ClientAuthenticationProcessingFilter filter =
                      new OAuth2ClientAuthenticationProcessingFilter(authConfig.getProperty("oauth2.filterCallbackPath"));
              filter.setRestTemplate(restTemplate);
              // Set a service that validates an OAuth2 access token
              // We can use either Google API's UserInfo or TokenInfo
              // For this, we chose to use UserInfo service
              filter.setTokenServices(googleUserInfoTokenServices());
              return filter;
          }
  
          @Bean           
          public GoogleUserInfoTokenServices googleUserInfoTokenServices() {
              GoogleUserInfoTokenServices userInfoTokenServices =
                      new GoogleUserInfoTokenServices(authConfig.getProperty("oauth2.userInfoUri"), authConfig.getProperty("oauth2.clientId"));
              // TODO Configure bean to use local database to read authorities
              // userInfoTokenServices.setAuthoritiesExtractor(authoritiesExtractor);
              return userInfoTokenServices;
          }
  
          @Bean
          public AuthenticationEntryPoint authenticationEntryPoint() {
              // May need an OAuth2AuthenticationEntryPoint for non-browser clients
              return new LoginUrlAuthenticationEntryPoint(authConfig.getProperty("oauth2.filterCallbackPath"));
          }
  
          @Override
          public void configure(WebSecurity web) throws Exception {
              web.ignoring().antMatchers(
                      "/", "/static/**", "/webjars/**");
          }
  
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http.exceptionHandling()
                          .authenticationEntryPoint(authenticationEntryPoint());
                  http
                      .antMatcher("/auth/oauth/**")                       
                      .authorizeRequests()
                          .anyRequest().authenticated()
                  .and()
                      .logout()
                          .logoutUrl("/logout")
                          .logoutSuccessUrl("/")                  
                  .and()
                      .addFilterAfter(
                          oauth2ClientContextFilter,
                          ExceptionTranslationFilter.class)
                      .addFilterBefore(
                          oauth2ClientAuthenticationProcessingFilter(),
                          FilterSecurityInterceptor.class)
                      .anonymous()                        
                          .disable();
          }
  
          @Override
          protected AuthenticationManager authenticationManager() throws Exception {
              return new NoopAuthenticationManager();
          }
  
  }
  
  private static class NoopAuthenticationManager implements AuthenticationManager {
      @Override
      public Authentication authenticate(Authentication authentication)
              throws AuthenticationException {
          throw new UnsupportedOperationException(
                  "No authentication should be done with this AuthenticationManager");
      }
  }
  
  @Bean           
  public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
      return new PropertySourcesPlaceholderConfigurer();
  }
  </code></pre>
  
  <p>While accessing the callback url <code>api/auth/oauth/callback</code>, I get following exception:</p>
  
  <blockquote>
    <p>org.springframework.beans.factory.BeanCreationException: Error
    creating bean with name 'scopedTarget.oauth2ClientContext': Scope
    'session' is not active for the current thread; consider defining a
    scoped proxy for this bean if you intend to refer to it from a
    singleton</p>
  </blockquote>
  
  <p>On searching SO, the suggested solution is to add <code>RequestContextListener</code> bean but even after adding that I got no success.</p>
  
  <p>One <a href="https://stackoverflow.com/questions/29817342/spring-deferred-result-request-scoped-beanoauth2clientcontext-in-the-web-fil">solution</a> also suggested using <code>FilterRegistrationBean</code> but I am not using Springboot so I am not sure whether it would have solved  my problem or not.</p>
  
  <p><strong>Full exception trace:</strong></p>
  
  <blockquote>
    <p>2018-02-22 12:47:36,440 - /api/auth/oauth/callback
    org.springframework.beans.factory.BeanCreationException: Error
    creating bean with name 'scopedTarget.oauth2ClientContext': Scope
    'session' is not active for the current thread; consider defining a
    scoped proxy for this bean if you intend to refer to it from a
    singleton; nested exception is java.lang.IllegalStateException: No
    thread-bound request found: Are you referring to request attributes
    outside of an actual web request, or processing a request outside of
    the originally receiving thread? If you are actually operating within
    a web request and still receive this message, your code is probably
    running outside of DispatcherServlet/DispatcherPortlet: In this case,
    use RequestContextListener or RequestContextFilter to expose the
    current request.  at
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355)
      at
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
      at
    org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
      at
    org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192)
      at com.sun.proxy.$Proxy64.getAccessToken(Unknown Source)    at
    org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:169)
      at
    org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:105)
      at
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter.doFilter(OAuth2ClientContextFilter.java:60)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
      at
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
      at
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
      at
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      at
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
      at
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
      at
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
      at
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
      at
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
      at
    org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
      at
    org.eclipse.jetty.servlets.UserAgentFilter.doFilter(UserAgentFilter.java:83)
      at
    org.eclipse.jetty.servlets.GzipFilter.doFilter(GzipFilter.java:364)
      at
    org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
      at
    org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
      at
    org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
      at
    org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
      at
    org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
      at
    org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
      at
    org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
      at
    org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
      at
    org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
      at
    org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
      at org.eclipse.jetty.server.Server.handle(Server.java:497)  at
    org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)     at
    org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
      at
    org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
      at
    org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
      at
    org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
      at java.lang.Thread.run(Unknown Source) Caused by:
    java.lang.IllegalStateException: No thread-bound request found: Are
    you referring to request attributes outside of an actual web request,
    or processing a request outside of the originally receiving thread? If
    you are actually operating within a web request and still receive this
    message, your code is probably running outside of
    DispatcherServlet/DispatcherPortlet: In this case, use
    RequestContextListener or RequestContextFilter to expose the current
    request.  at
    org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
      at
    org.springframework.web.context.request.SessionScope.get(SessionScope.java:91)
      at
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340)
      ... 55 more</p>
  </blockquote>