spring-attic / spring-cloud-security

Security concerns for distributed applications implemented in Spring
Apache License 2.0
531 stars 245 forks source link

OAuth2FeignRequestInterceptor do not reauthentificate when refresh token is expired #224

Closed michmzr closed 3 years ago

michmzr commented 4 years ago

Hi guys,

Does OAuth2FeignRequestInterceptor support flow for 401 error - expired refresh token? Our microservice used to throw error, when It was trying to get a new access token.

I created a temporary working interceptor (https://gist.github.com/michmzr/5726648b0cc81a1dee89ecf5f5c4c94b#file-feignrequestinterceptor-java ), but I would like to know whats a suggested solution to automatically handle all oauth2 401 errors for microservices. Oauth2 grant type is password

We use Feign Client to make REST requests.

Feign client version: 2.1.3.RELEASE Spring Boot: 2.0.5.RELEASE Spring Cloud Security: 2.0.0 RELEASE

Log error:

2019-10-17T10:30:33:724Z [http-nio-8096-exec-2] ERROR o.s.s.o.p.endpoint.TokenEndpoint - Handling error: InvalidTokenException, Invalid refresh token (expired): 4a61b640-40c5-4c1e-9844-fc0d8c09eb71 
        org.springframework.security.oauth2.common.exceptions.InvalidTokenException: Invalid refresh token (expired): 4a61b640-40c5-4c1e-9844-fc0d8c09eb71 
        at org.springframework.security.oauth2.provider.token.DefaultTokenServices.refreshAccessToken(DefaultTokenServices.java:166) 
        at org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter.getAccessToken(RefreshTokenGranter.java:47) 
        at org.springframework.security.oauth2.provider.token.AbstractTokenGranter.grant(AbstractTokenGranter.java:65) 
        at org.springframework.security.oauth2.provider.CompositeTokenGranter.grant(CompositeTokenGranter.java:38) 
        at org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer$4.grant(AuthorizationServerEndpointsConfigurer.java:561) 
        at org.springframework.security.oauth2.provider.endpoint.TokenEndpoint.postAccessToken(TokenEndpoint.java:132) 
        at sun.reflect.GeneratedMethodAccessor182.invoke(Unknown Source) 
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
        at java.lang.reflect.Method.invoke(Method.java:498) 
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) 
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) 
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) 
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) 
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) 
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) 
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) 
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) 
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) 
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) 
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) 
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) 
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158) 
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126) 
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:84) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) 
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) 
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:215) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) 
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
        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:334) 
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) 
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) 
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) 
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at com.imshealth.rdf.mb.security.server.configuration.CORSFilter.doFilter(CORSFilter.java:39) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) 
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) 
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) 
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) 
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) 
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) 
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) 
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) 
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
        at java.lang.Thread.run(Thread.java:748)
josecarlossobrino commented 4 years ago

Is there any solution for this error? I have the same one...

Feign client version: 2.1.0.RELEASE Spring Boot: 2.1.9.RELEASE Spring Cloud Security: 2.1.0 RELEASE

michmzr commented 4 years ago

@josecarlossobrino I created workaround https://github.com/OpenFeign/feign/issues/1100#event-2745277093

josecarlossobrino commented 4 years ago

Yes, @michmzr, I saw it. I've just added to my project, with a couple of changes, and it works! Thanks a lot!

spencergibb commented 3 years ago

fixed in openfeign