Error creating bean with name 'scopedTarget.oauth2ClientContext' despite defining RequestContextListener
Solution 1
I solved the problem. And in this era of Springboot
, someone who is working on a slightly older system, might find the answer useful, so sharing it.
The RequestContextListener
needs to be added in jetty configuration like this:
context.addEventListener(new RequestContextListener());
I was adding it in my security config file, like this:
@Bean
@Order(0)
public RequestContextListener requestContextListener() {
return new RequestContextListener();
}
Solution 2
Someone can find this useful, add following in AbstractAnnotationConfigDispatcherServletInitializer implemntation class:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addListener(new RequestContextListener());
}
tryingToLearn
Coder. Rookie blogger. Perpetually curious. Dreamer. Big fan of open source community. Loves programming and exploring new technical fields.
Updated on June 04, 2022Comments
-
tryingToLearn almost 2 years
My app has multiple spring security configurations and one of them happens to be
Oauth2
(using this eaxmple).Spring security in general is getting plugged in via:
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/*");
Oauth2 which looks like this:
@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(); }
While accessing the callback url
api/auth/oauth/callback
, I get following exception: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
On searching SO, the suggested solution is to add
RequestContextListener
bean but even after adding that I got no success.One solution also suggested using
FilterRegistrationBean
but I am not using Springboot so I am not sure whether it would have solved my problem or not.Full exception trace:
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
-
tryingToLearn almost 6 yearsThe scenario described in your question is slightly different. As I mentioned in my answer, this solution is for non-Springboot apps.
-
Reginaldo Santos over 5 yearsU've saved my day! Tks for sharing.