Spring Authorization Server 1.0 sample federated-identity-authorizationserver gives invalid_token_response - spring-security

I am trying out federated-identity-authorizationserver sample given in sample.
I updated the yml files as required.
I was able to start auth server and resource server.
While starting client I got provider issuer error which I resolved by updating client yml as below
provider:
spring:
authorization-uri: http://localhost:9000/oauth2/authorize
token-uri: http://localhost:9000/oauth2/token
#issuer-uri: http://localhost:9000
I am able to start the messaging client and able to perform authentication with google but getting below error. I am getting same error if I try it with local auth server using user1/password credentials.
{"exception":"[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [text/html;charset=utf-8]","timestamp":1674192821362}
To get the error I added failureHandler as below otherwise I was getting too many redirects error.
#Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize ->
authorize.anyRequest().authenticated()
)
.oauth2Login(oauth2Login ->
oauth2Login.loginPage("/oauth2/authorization/messaging-client-oidc").successHandler(new LoginSuccessHandler()).failureHandler(new CustomAuthenticationFailureHandler()))
.oauth2Client(withDefaults());
return http.build();
I also tried adding accessTokenResponseClient as below but error remains same and the accessTokenResponseClient to the client config but it is not getting invoked. I have authorizationCodeTokenResponseClient() and other relevant classes.
.oauth2Login(oauth2Login ->
oauth2Login
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenResponseClient(authorizationCodeTokenResponseClient()))
.loginPage("/oauth2/authorization/messaging-client-oidc").successHandler(new LoginSuccessHandler()).failureHandler(new CustomAuthenticationFailureHandler()))
.oauth2Client(withDefaults());
I am getting above error when I try with local auth server and Google as a federated auth server.
The debug trace from client just before the error. the code is matching the federated server code
2023-01-24T22:24:59.078+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [classpath [META-INF/resources/], classpath [resources/], classpath [static/], classpath [public/], ServletContext [/]]
2023-01-24T22:24:59.079+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Securing GET /login/oauth2/code/messaging-client-oidc?code=DxWgpwZqmepYInMZ0lBZrboaEVULZYep8r2I9Kz6MM9rY-2O2Bg1wSMiKPhwMM2U2Uf9bvd2N9pMFXbB7mCKw4GlDULdgNSADjHOzXQxdEGRNPtRVBU7i6OKfkxCtB7i&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D
2023-01-24T22:24:59.092+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : HTTP POST http://localhost:9000/oauth2/token
2023-01-24T22:24:59.095+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : Accept=[application/json, application/*+json]
2023-01-24T22:24:59.096+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : Writing [{grant_type=[authorization_code], code=[DxWgpwZqmepYInMZ0lBZrboaEVULZYep8r2I9Kz6MM9rY-2O2Bg1wSMiKPhwMM2U2Uf9bvd2N9pMFXbB7mCKw4GlDULdgNSADjHOzXQxdEGRNPtRVBU7i6OKfkxCtB7i], redirect_uri=[http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc]}] as "application/x-www-form-urlencoded;charset=UTF-8"
2023-01-24T22:24:59.276+05:30 DEBUG 96239 --- [nio-8080-exec-5] o.s.web.client.RestTemplate : Response 200 OK
2023-01-24T22:24:59.284+05:30 DEBUG 96239 --- [nio-8080-exec-5] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [text/html;charset=utf-8]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.getResponse(OidcAuthorizationCodeAuthenticationProvider.java:176) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:144) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:195) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:231) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.doFilterInternal(OAuth2AuthorizationRequestRedirectFilter.java:181) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:107) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:93) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:116) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.context.SecurityContextHolderFilter.doFilterInternal(SecurityContextHolderFilter.java:69) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:62) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.session.DisableEncodeUrlFilter.doFilterInternal(DisableEncodeUrlFilter.java:42) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:233) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) ~[spring-security-web-6.0.0.jar:6.0.0]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:351) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.2.jar:6.0.2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.2.jar:6.0.2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:185) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:158) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:119) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:400) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1739) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.1.jar:10.1.1]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: org.springframework.security.oauth2.core.OAuth2AuthorizationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Could not extract response: no suitable HttpMessageConverter found for response type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [text/html;charset=utf-8]
at org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient.getResponse(DefaultAuthorizationCodeTokenResponseClient.java:95) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient.getTokenResponse(DefaultAuthorizationCodeTokenResponseClient.java:77) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient.getTokenResponse(DefaultAuthorizationCodeTokenResponseClient.java:56) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.getResponse(OidcAuthorizationCodeAuthenticationProvider.java:170) ~[spring-security-oauth2-client-6.0.0.jar:6.0.0]
... 62 common frames omitted
The debug trace from auth server
2023-01-24T22:24:54.510+05:30 INFO 96235 --- [nio-9000-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
2023-01-24T22:24:54.518+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.security.web.FilterChainProxy : Securing GET /oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws
2023-01-24T22:24:54.581+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-01-24T22:24:54.608+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.s.w.s.HttpSessionRequestCache : Saved request http://localhost:9000/oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws&continue to session
2023-01-24T22:24:54.609+05:30 DEBUG 96235 --- [nio-9000-exec-1] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:9000/login
2023-01-24T22:24:54.615+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy : Securing GET /login
2023-01-24T22:24:54.625+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.627+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.627+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.627+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.security.web.FilterChainProxy : Secured GET /login
2023-01-24T22:24:54.630+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.web.servlet.DispatcherServlet : GET "/login", parameters={}
2023-01-24T22:24:54.632+05:30 DEBUG 96235 --- [nio-9000-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to sample.web.LoginController#login()
2023-01-24T22:24:54.647+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
2023-01-24T22:24:54.889+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.web.servlet.DispatcherServlet : Completed 200 OK
2023-01-24T22:24:54.889+05:30 DEBUG 96235 --- [nio-9000-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2023-01-24T22:24:56.340+05:30 DEBUG 96235 --- [nio-9000-exec-3] o.s.security.web.FilterChainProxy : Securing GET /oauth2/authorization/google-idp
2023-01-24T22:24:56.351+05:30 DEBUG 96235 --- [nio-9000-exec-3] o.s.s.web.DefaultRedirectStrategy : Redirecting to https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=12345&scope=openid%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email&state=LiD_tN32DWHRqSqplicP6DmLk9oYl4_jcW0koqBe4uc%3D&redirect_uri=http://localhost:9000/login/oauth2/code/google-idp&nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck
2023-01-24T22:24:56.661+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.security.web.FilterChainProxy : Securing GET /login/oauth2/code/google-idp?state=LiD_tN32DWHRqSqplicP6DmLk9oYl4_jcW0koqBe4uc%3D&code=4%2F0AWtgzh5Qn1pSQP9samBXt-s-A9NUT0LBaC0iwCps44rQnq1M7wVMG-bd5DQj_0HMaSLSRA&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=none
2023-01-24T22:24:56.743+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : HTTP POST https://www.googleapis.com/oauth2/v4/token
2023-01-24T22:24:56.747+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Accept=[application/json, application/*+json]
2023-01-24T22:24:56.748+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Writing [{grant_type=[authorization_code], code=[4/0AWtgzh5Qn1pSQP9samBXt-s-A9NUT0LBaC0iwCps44rQnq1M7wVMG-bd5DQj_0HMaSLSRA], redirect_uri=[http://localhost:9000/login/oauth2/code/google-idp]}] as "application/x-www-form-urlencoded;charset=UTF-8"
2023-01-24T22:24:57.051+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Response 200 OK
2023-01-24T22:24:57.052+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Reading to [org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] as "application/json;charset=utf-8"
2023-01-24T22:24:57.093+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : HTTP GET https://www.googleapis.com/oauth2/v3/certs
2023-01-24T22:24:57.094+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Accept=[text/plain, application/json, application/*+json, */*]
2023-01-24T22:24:57.118+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Response 200 OK
2023-01-24T22:24:57.118+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.web.client.RestTemplate : Reading to [java.lang.String] as "application/json;charset=UTF-8"
2023-01-24T22:24:57.125+05:30 DEBUG 96235 --- [nio-9000-exec-4] .s.ChangeSessionIdAuthenticationStrategy : Changed session id from 856E5CB5EA53F6364793E21162F85AF2
2023-01-24T22:24:57.125+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.s.w.csrf.CsrfAuthenticationStrategy : Replaced CSRF Token
2023-01-24T22:24:57.126+05:30 DEBUG 96235 --- [nio-9000-exec-4] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade#46dcae35]
2023-01-24T22:24:57.126+05:30 DEBUG 96235 --- [nio-9000-exec-4] .s.o.c.w.OAuth2LoginAuthenticationFilter : Set SecurityContextHolder to OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]
Saving first-time user: name=***#gmail.com, claims={at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}, authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]
2023-01-24T22:24:57.126+05:30 DEBUG 96235 --- [nio-9000-exec-4] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://localhost:9000/oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws&continue
2023-01-24T22:24:57.129+05:30 DEBUG 96235 --- [nio-9000-exec-5] o.s.security.web.FilterChainProxy : Securing GET /oauth2/authorize?response_type=code&client_id=messaging-client&scope=openid%20profile&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D&redirect_uri=http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc&nonce=FTOwMi9WPU3zHBPBrG2Jj-Dxm0udS_dLfI1I0TiN2Ws&continue
2023-01-24T22:24:57.130+05:30 DEBUG 96235 --- [nio-9000-exec-5] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]]
2023-01-24T22:24:59.025+05:30 DEBUG 96235 --- [nio-9000-exec-6] o.s.security.web.FilterChainProxy : Securing POST /oauth2/authorize
2023-01-24T22:24:59.026+05:30 DEBUG 96235 --- [nio-9000-exec-6] w.c.HttpSessionSecurityContextRepository : Retrieved SecurityContextImpl [Authentication=OAuth2AuthenticationToken [Principal=Name: [***#gmail.com], Granted Authorities: [[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]], User Attributes: [{at_hash=ao1nlr-mAYrpo3nU3ODFUQ, sub=107668940011151070771, email_verified=true, iss=https://accounts.google.com, given_name=***, locale=en-GB, nonce=mEbeJ8BYMUG2snc7fQgr-BhvBd1Gw4SYIZsch6rp7Ck, picture=https://lh3.googleusercontent.com/a/AEdFTp75Udyj3805vIwRZpzku1-cRpiFpuMWsivqzRa9=s96-c, aud=[12345], azp=12345, name=*** *, exp=2023-01-24T17:54:57Z, family_name=*, iat=2023-01-24T16:54:57Z, email=***#gmail.com}], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=856E5CB5EA53F6364793E21162F85AF2], Granted Authorities=[OIDC_USER, SCOPE_https://www.googleapis.com/auth/userinfo.email, SCOPE_https://www.googleapis.com/auth/userinfo.profile, SCOPE_openid]]]
2023-01-24T22:24:59.074+05:30 DEBUG 96235 --- [nio-9000-exec-6] o.s.s.web.DefaultRedirectStrategy : Redirecting to http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc?code=DxWgpwZqmepYInMZ0lBZrboaEVULZYep8r2I9Kz6MM9rY-2O2Bg1wSMiKPhwMM2U2Uf9bvd2N9pMFXbB7mCKw4GlDULdgNSADjHOzXQxdEGRNPtRVBU7i6OKfkxCtB7i&state=2gTNT52oxL3kRqtnbA0vnXQzp3VrghJmLtVUNEtagRo%3D

Related

Spring Authorization Server - Client Credentials flow - no session created on POST to /oauth2/token

I am testing spring-authorization-server 0.2.1 with a simple application with a REST Controller to return a String on GET ("/message").
POST to "/oauth2/token" with BASIC Auth Header will successfully retrieve JWT token, but when client use the token, application will reply with 403 Forbidden.
The flow looks like this:
POST /oauth2/token
Response 200 OK with access_token_a
GET /message with Authorization: "Bearer account_token_a"
Response 403 Forbidden
POST /oauth2/token
Response 200 OK with access_token_b
GET /message with Authorization: "Bearer account_token_b"
Response 200 OK with Body Hello There
Checking the logs I can see that in the first POST to get access_token (1), no HTTP session is created and thus the SecurityContext is not stored in the session.
2022-01-10 15:27:53.971 DEBUG 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Securing POST /oauth2/token
2022-01-10 15:27:53.973 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (1/20)
2022-01-10 15:27:53.979 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking SecurityContextPersistenceFilter (2/20)
2022-01-10 15:27:53.980 TRACE 25384 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2022-01-10 15:27:53.981 TRACE 25384 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : Created SecurityContextImpl [Null authentication]
2022-01-10 15:27:53.983 DEBUG 25384 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-01-10 15:27:53.984 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking HeaderWriterFilter (3/20)
2022-01-10 15:27:53.984 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking CsrfFilter (4/20)
2022-01-10 15:27:53.986 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.csrf.CsrfFilter : Did not protect against CSRF since request did not match And [CsrfNotRequired [TRACE, HEAD, GET, OPTIONS], Not [Or [org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer$$Lambda$603/0x000000080043d040#3811510]]]
2022-01-10 15:27:53.986 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking LogoutFilter (5/20)
2022-01-10 15:27:53.987 TRACE 25384 --- [nio-8080-exec-1] o.s.s.w.a.logout.LogoutFilter : Did not match request to Ant [pattern='/logout', POST]
2022-01-10 15:27:53.987 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking OAuth2AuthorizationEndpointFilter (6/20)
2022-01-10 15:27:53.987 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking OidcProviderConfigurationEndpointFilter (7/20)
2022-01-10 15:27:53.987 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking NimbusJwkSetEndpointFilter (8/20)
2022-01-10 15:27:53.987 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking OAuth2AuthorizationServerMetadataEndpointFilter (9/20)
2022-01-10 15:27:53.988 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking OAuth2ClientAuthenticationFilter (10/20)
2022-01-10 15:27:53.991 TRACE 25384 --- [nio-8080-exec-1] o.s.s.authentication.ProviderManager : Authenticating request with OAuth2ClientAuthenticationProvider (1/9)
2022-01-10 15:27:53.991 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking RequestCacheAwareFilter (11/20)
2022-01-10 15:27:53.991 TRACE 25384 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache : No saved request
2022-01-10 15:27:53.991 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (12/20)
2022-01-10 15:27:53.993 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (13/20)
2022-01-10 15:27:53.993 TRACE 25384 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter : Did not set SecurityContextHolder since already authenticated OAuth2ClientAuthenticationToken [Principal=prometheus-client, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=null], Granted Authorities=[]]
2022-01-10 15:27:53.993 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking SessionManagementFilter (14/20)
2022-01-10 15:27:53.993 TRACE 25384 --- [nio-8080-exec-1] s.CompositeSessionAuthenticationStrategy : Preparing session with ChangeSessionIdAuthenticationStrategy (1/2)
2022-01-10 15:27:53.994 TRACE 25384 --- [nio-8080-exec-1] s.CompositeSessionAuthenticationStrategy : Preparing session with CsrfAuthenticationStrategy (2/2)
2022-01-10 15:27:53.997 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (15/20)
2022-01-10 15:27:53.997 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking FilterSecurityInterceptor (16/20)
2022-01-10 15:27:53.997 TRACE 25384 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Did not re-authenticate OAuth2ClientAuthenticationToken [Principal=prometheus-client, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=null], Granted Authorities=[]] before authorizing
2022-01-10 15:27:53.998 TRACE 25384 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Authorizing filter invocation [POST /oauth2/token] with attributes [authenticated]
2022-01-10 15:27:54.003 DEBUG 25384 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Authorized filter invocation [POST /oauth2/token] with attributes [authenticated]
2022-01-10 15:27:54.004 TRACE 25384 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Did not switch RunAs authentication since RunAsManager returned null
2022-01-10 15:27:54.004 TRACE 25384 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy : Invoking OAuth2TokenEndpointFilter (17/20)
2022-01-10 15:27:54.010 TRACE 25384 --- [nio-8080-exec-1] o.s.s.authentication.ProviderManager : Authenticating request with OAuth2ClientCredentialsAuthenticationProvider (1/9)
2022-01-10 15:27:54.147 TRACE 25384 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure]
2022-01-10 15:27:54.152 DEBUG 25384 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
HTTP Session will be created on the GET request (3), but no SecurityContext will be found thus the request will fail with 403 Forbidden
2022-01-10 15:27:59.854 DEBUG 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Securing GET /message
2022-01-10 15:27:59.855 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (1/11)
2022-01-10 15:27:59.855 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking SecurityContextPersistenceFilter (2/11)
2022-01-10 15:27:59.876 DEBUG 25384 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Created session FC68E4563F8E775A591D1632F2C7456E eagerly
2022-01-10 15:27:59.876 TRACE 25384 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not find SecurityContext in HttpSession FC68E4563F8E775A591D1632F2C7456E using the SPRING_SECURITY_CONTEXT session attribute
2022-01-10 15:27:59.876 TRACE 25384 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Created SecurityContextImpl [Null authentication]
2022-01-10 15:27:59.876 DEBUG 25384 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-01-10 15:27:59.876 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking HeaderWriterFilter (3/11)
2022-01-10 15:27:59.876 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking CsrfFilter (4/11)
2022-01-10 15:27:59.876 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.csrf.CsrfFilter : Did not protect against CSRF since request did not match CsrfNotRequired [TRACE, HEAD, GET, OPTIONS]
2022-01-10 15:27:59.877 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking LogoutFilter (5/11)
2022-01-10 15:27:59.877 TRACE 25384 --- [nio-8080-exec-2] o.s.s.w.a.logout.LogoutFilter : Did not match request to Ant [pattern='/logout', POST]
2022-01-10 15:27:59.877 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking RequestCacheAwareFilter (6/11)
2022-01-10 15:27:59.877 TRACE 25384 --- [nio-8080-exec-2] o.s.s.w.s.HttpSessionRequestCache : No saved request
2022-01-10 15:27:59.877 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (7/11)
2022-01-10 15:27:59.877 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (8/11)
2022-01-10 15:27:59.877 TRACE 25384 --- [nio-8080-exec-2] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=FC68E4563F8E775A591D1632F2C7456E], Granted Authorities=[ROLE_ANONYMOUS]]
2022-01-10 15:27:59.878 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking SessionManagementFilter (9/11)
2022-01-10 15:27:59.878 DEBUG 25384 --- [nio-8080-exec-2] o.s.s.w.session.SessionManagementFilter : Request requested invalid session id A75734F37AD5AA7C76AA39F041B1C505
2022-01-10 15:27:59.878 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (10/11)
2022-01-10 15:27:59.878 TRACE 25384 --- [nio-8080-exec-2] o.s.security.web.FilterChainProxy : Invoking AuthorizationFilter (11/11)
2022-01-10 15:27:59.880 TRACE 25384 --- [nio-8080-exec-2] estMatcherDelegatingAuthorizationManager : Authorizing SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest#764a97f0]
2022-01-10 15:27:59.880 TRACE 25384 --- [nio-8080-exec-2] estMatcherDelegatingAuthorizationManager : Checking authorization on SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest#764a97f0] using org.springframework.security.authorization.AuthenticatedAuthorizationManager#a2fdca
2022-01-10 15:27:59.889 TRACE 25384 --- [nio-8080-exec-2] o.s.s.w.a.ExceptionTranslationFilter : Sending AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=FC68E4563F8E775A591D1632F2C7456E], Granted Authorities=[ROLE_ANONYMOUS]] to authentication entry point since access is denied
org.springframework.security.access.AccessDeniedException: Access Denied
at org.springframework.security.authorization.AuthorizationManager.verify(AuthorizationManager.java:44) ~[spring-security-core-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.intercept.AuthorizationFilter.doFilterInternal(AuthorizationFilter.java:57) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:117) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.6.1.jar:5.6.1]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.14.jar:5.3.14]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.14.jar:5.3.14]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.14.jar:5.3.14]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.56.jar:9.0.56]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
2022-01-10 15:27:59.898 DEBUG 25384 --- [nio-8080-exec-2] o.s.s.w.s.HttpSessionRequestCache : Saved request http://10.20.1.192:8080/message to session
2022-01-10 15:27:59.898 DEBUG 25384 --- [nio-8080-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2022-01-10 15:27:59.898 TRACE 25384 --- [nio-8080-exec-2] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure]
2022-01-10 15:27:59.898 DEBUG 25384 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-01-10 15:27:59.898 DEBUG 25384 --- [nio-8080-exec-2] w.c.HttpSessionSecurityContextRepository : Did not store empty SecurityContext
2022-01-10 15:27:59.898 DEBUG 25384 --- [nio-8080-exec-2] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
On the second POST to get a new JWT token (5), HTTP Session is present, thus the SecurityContext will be saved there and reused for later. And as a result, GET request (7) will succeed.
2022-01-10 15:28:08.152 DEBUG 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Securing POST /oauth2/token
2022-01-10 15:28:08.152 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking WebAsyncManagerIntegrationFilter (1/20)
2022-01-10 15:28:08.152 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking SecurityContextPersistenceFilter (2/20)
2022-01-10 15:28:08.153 TRACE 25384 --- [nio-8080-exec-3] w.c.HttpSessionSecurityContextRepository : Did not find SecurityContext in HttpSession FC68E4563F8E775A591D1632F2C7456E using the SPRING_SECURITY_CONTEXT session attribute
2022-01-10 15:28:08.153 TRACE 25384 --- [nio-8080-exec-3] w.c.HttpSessionSecurityContextRepository : Created SecurityContextImpl [Null authentication]
2022-01-10 15:28:08.153 DEBUG 25384 --- [nio-8080-exec-3] s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
2022-01-10 15:28:08.153 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking HeaderWriterFilter (3/20)
2022-01-10 15:28:08.153 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking CsrfFilter (4/20)
2022-01-10 15:28:08.153 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.csrf.CsrfFilter : Did not protect against CSRF since request did not match And [CsrfNotRequired [TRACE, HEAD, GET, OPTIONS], Not [Or [org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization.OAuth2AuthorizationServerConfigurer$$Lambda$603/0x000000080043d040#3811510]]]
2022-01-10 15:28:08.153 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking LogoutFilter (5/20)
2022-01-10 15:28:08.153 TRACE 25384 --- [nio-8080-exec-3] o.s.s.w.a.logout.LogoutFilter : Did not match request to Ant [pattern='/logout', POST]
2022-01-10 15:28:08.154 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking OAuth2AuthorizationEndpointFilter (6/20)
2022-01-10 15:28:08.154 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking OidcProviderConfigurationEndpointFilter (7/20)
2022-01-10 15:28:08.154 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking NimbusJwkSetEndpointFilter (8/20)
2022-01-10 15:28:08.154 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking OAuth2AuthorizationServerMetadataEndpointFilter (9/20)
2022-01-10 15:28:08.154 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking OAuth2ClientAuthenticationFilter (10/20)
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] o.s.s.authentication.ProviderManager : Authenticating request with OAuth2ClientAuthenticationProvider (1/9)
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking RequestCacheAwareFilter (11/20)
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] o.s.s.w.s.HttpSessionRequestCache : Did not match request /oauth2/token to the saved one DefaultSavedRequest [http://10.20.1.192:8080/message]
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking SecurityContextHolderAwareRequestFilter (12/20)
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking AnonymousAuthenticationFilter (13/20)
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] o.s.s.w.a.AnonymousAuthenticationFilter : Did not set SecurityContextHolder since already authenticated OAuth2ClientAuthenticationToken [Principal=prometheus-client, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=FC68E4563F8E775A591D1632F2C7456E], Granted Authorities=[]]
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking SessionManagementFilter (14/20)
2022-01-10 15:28:08.155 TRACE 25384 --- [nio-8080-exec-3] s.CompositeSessionAuthenticationStrategy : Preparing session with ChangeSessionIdAuthenticationStrategy (1/2)
2022-01-10 15:28:08.156 DEBUG 25384 --- [nio-8080-exec-3] .s.ChangeSessionIdAuthenticationStrategy : Changed session id from FC68E4563F8E775A591D1632F2C7456E
2022-01-10 15:28:08.158 TRACE 25384 --- [nio-8080-exec-3] s.CompositeSessionAuthenticationStrategy : Preparing session with CsrfAuthenticationStrategy (2/2)
2022-01-10 15:28:08.159 DEBUG 25384 --- [nio-8080-exec-3] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=OAuth2ClientAuthenticationToken [Principal=prometheus-client, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=FC68E4563F8E775A591D1632F2C7456E], Granted Authorities=[]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade#7f25256d]
2022-01-10 15:28:08.159 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking ExceptionTranslationFilter (15/20)
2022-01-10 15:28:08.159 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking FilterSecurityInterceptor (16/20)
2022-01-10 15:28:08.159 TRACE 25384 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Did not re-authenticate OAuth2ClientAuthenticationToken [Principal=prometheus-client, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=FC68E4563F8E775A591D1632F2C7456E], Granted Authorities=[]] before authorizing
2022-01-10 15:28:08.159 TRACE 25384 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Authorizing filter invocation [POST /oauth2/token] with attributes [authenticated]
2022-01-10 15:28:08.160 DEBUG 25384 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Authorized filter invocation [POST /oauth2/token] with attributes [authenticated]
2022-01-10 15:28:08.160 TRACE 25384 --- [nio-8080-exec-3] o.s.s.w.a.i.FilterSecurityInterceptor : Did not switch RunAs authentication since RunAsManager returned null
2022-01-10 15:28:08.160 TRACE 25384 --- [nio-8080-exec-3] o.s.security.web.FilterChainProxy : Invoking OAuth2TokenEndpointFilter (17/20)
2022-01-10 15:28:08.160 TRACE 25384 --- [nio-8080-exec-3] o.s.s.authentication.ProviderManager : Authenticating request with OAuth2ClientCredentialsAuthenticationProvider (1/9)
2022-01-10 15:28:08.181 TRACE 25384 --- [nio-8080-exec-3] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match request to [Is Secure]
2022-01-10 15:28:08.182 DEBUG 25384 --- [nio-8080-exec-3] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=OAuth2ClientAuthenticationToken [Principal=prometheus-client, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=FC68E4563F8E775A591D1632F2C7456E], Granted Authorities=[]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade#7f25256d]
2022-01-10 15:28:08.182 DEBUG 25384 --- [nio-8080-exec-3] w.c.HttpSessionSecurityContextRepository : Stored SecurityContextImpl [Authentication=OAuth2ClientAuthenticationToken [Principal=prometheus-client, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=10.20.1.192, SessionId=FC68E4563F8E775A591D1632F2C7456E], Granted Authorities=[]]] to HttpSession [org.apache.catalina.session.StandardSessionFacade#7f25256d]
2022-01-10 15:28:08.182 DEBUG 25384 --- [nio-8080-exec-3] s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
I am using configuration https://github.com/spring-projects/spring-security-samples/blob/main/servlet/spring-boot/java/oauth2/authorization-server/src/main/java/example/OAuth2AuthorizationServerSecurityConfiguration.java but with login page disabled.
Is this a bug or something wrong in the configuration?
Thanks
Since you're using client_credentials, you shouldn't be relying on a session. You also don't need a second filter chain with formLogin() disabled.
Upon investigating your sample, it looks as though you're attempting to include a resource server (the Simple controller) in your authorization server. This is an incorrect setup. It should be a separately deployed application and properly configured as a resource server, as in the samples provided in the project.

How to bypass some urls in spring webflux security?

I have a spring webflux application and has enabled spring webflux security using below code:-
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
log.debug("Configuring tenant web security");
return http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated()
.and()
.addFilterAt(authenticationWebFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.addFilterAt(authorizationWebFilter(), SecurityWebFiltersOrder.AUTHORIZATION)
.build();
}
private AuthenticationWebFilter authenticationWebFilter() {
AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(
customAuthenticationManager);
authenticationWebFilter.setServerAuthenticationConverter(customAuthenticationConverter);
return authenticationWebFilter;
}
private AuthorizationWebFilter authorizationWebFilter() {
return new AuthorizationWebFilter(customAuthorizationManager);
}
I want to bypass the actuator urls mentioned in code but somehow they are still getting in ServerAuthenticationConverter class which I have overriden to parse the headers.
I am making request for localhost:8082/actuator/health and it is still going through all the security chain.
What am I doing wrong in here?
This below link is related to this issue but couldn't find any helpful answers:-
How to exclude a path from authentication in a spring based reactive application?
Debug logs with exception:-
2021-05-27 21:11:50.496 DEBUG 87018 --- [ctor-http-nio-3] io.netty.buffer.AbstractByteBuf : -Dio.netty.buffer.checkBounds: true
2021-05-27 21:11:50.497 DEBUG 87018 --- [ctor-http-nio-3] i.n.util.ResourceLeakDetectorFactory : Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector#1afad0f4
2021-05-27 21:11:50.510 DEBUG 87018 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations : [id: 0xdbf63e0b, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53830] New http connection, requesting read
2021-05-27 21:11:50.510 DEBUG 87018 --- [ctor-http-nio-2] r.n.http.server.HttpServerOperations : [id: 0x3302bee3, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53829] New http connection, requesting read
2021-05-27 21:11:50.510 DEBUG 87018 --- [ctor-http-nio-2] reactor.netty.transport.TransportConfig : [id: 0x3302bee3, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53829] Initialized pipeline DefaultChannelPipeline{(reactor.left.httpCodec = io.netty.handler.codec.http.HttpServerCodec), (reactor.left.httpTrafficHandler = reactor.netty.http.server.HttpTrafficHandler), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
2021-05-27 21:11:50.510 DEBUG 87018 --- [ctor-http-nio-3] reactor.netty.transport.TransportConfig : [id: 0xdbf63e0b, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53830] Initialized pipeline DefaultChannelPipeline{(reactor.left.httpCodec = io.netty.handler.codec.http.HttpServerCodec), (reactor.left.httpTrafficHandler = reactor.netty.http.server.HttpTrafficHandler), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
2021-05-27 21:11:50.516 DEBUG 87018 --- [ctor-http-nio-3] io.netty.util.Recycler : -Dio.netty.recycler.maxCapacityPerThread: 4096
2021-05-27 21:11:50.516 DEBUG 87018 --- [ctor-http-nio-3] io.netty.util.Recycler : -Dio.netty.recycler.maxSharedCapacityFactor: 2
2021-05-27 21:11:50.516 DEBUG 87018 --- [ctor-http-nio-3] io.netty.util.Recycler : -Dio.netty.recycler.linkCapacity: 16
2021-05-27 21:11:50.516 DEBUG 87018 --- [ctor-http-nio-3] io.netty.util.Recycler : -Dio.netty.recycler.ratio: 8
2021-05-27 21:11:50.516 DEBUG 87018 --- [ctor-http-nio-3] io.netty.util.Recycler : -Dio.netty.recycler.delayedQueue.ratio: 8
2021-05-27 21:11:50.542 DEBUG 87018 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations : [id: 0xdbf63e0b, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53830] Increasing pending responses, now 1
2021-05-27 21:11:50.547 DEBUG 87018 --- [ctor-http-nio-3] reactor.netty.http.server.HttpServer : [id: 0xdbf63e0b, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53830] Handler is being applied: org.springframework.http.server.reactive.ReactorHttpHandlerAdapter#60ba6618
2021-05-27 21:11:50.553 DEBUG 87018 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter : [dbf63e0b-1] HTTP GET "/actuator/health"
2021-05-27 21:11:50.589 WARN 87018 --- [ctor-http-nio-3] c.r.c.a.c.e.RestWebExceptionHandler : Web request for uri http://localhost:8082/actuator/health failed with exception java.lang.IllegalArgumentException: X-Auth header is not present.
at com.demo.ceresgateway.app.config.security.CustomServerAuthenticationConverter.resolveHeaders(CustomServerAuthenticationConverter.java:61)
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ org.springframework.security.web.server.authentication.AuthenticationWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP GET "/actuator/health" [ExceptionHandlingWebHandler]
Stack trace:
at com.demo.ceresgateway.app.config.security.CustomServerAuthenticationConverter.resolveHeaders(CustomServerAuthenticationConverter.java:61)
at com.demo.ceresgateway.app.config.security.CustomServerAuthenticationConverter.convert(CustomServerAuthenticationConverter.java:31)
at org.springframework.security.web.server.authentication.AuthenticationWebFilter.lambda$filter$2(AuthenticationWebFilter.java:112)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:125)
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118)
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2346)
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110)
at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:87)
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1784)
at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:249)
at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1784)
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onComplete(MonoCollectList.java:128)
at reactor.core.publisher.FluxIterable$IterableSubscription.fastPath(FluxIterable.java:360)
at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:225)
at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onSubscribe(MonoCollectList.java:79)
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164)
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86)
at reactor.core.publisher.MonoFromFluxOperator.subscribe(MonoFromFluxOperator.java:81)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73)
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.drain(FluxFilterWhen.java:301)
at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.onNext(FluxFilterWhen.java:140)
at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:270)
at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:228)
at reactor.core.publisher.FluxFilterWhen$FluxFilterWhenSubscriber.onSubscribe(FluxFilterWhen.java:200)
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164)
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
at reactor.core.publisher.Mono.subscribe(Mono.java:4046)
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:173)
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
at reactor.netty.http.server.HttpServer$HttpServerHandle.onStateChange(HttpServer.java:632)
at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:612)
at reactor.netty.transport.ServerTransport$ChildObserver.onStateChange(ServerTransport.java:453)
at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:510)
at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:208)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:832)
2021-05-27 21:11:50.595 DEBUG 87018 --- [ctor-http-nio-3] a.w.r.e.AbstractErrorWebExceptionHandler : [dbf63e0b-1] Resolved [IllegalArgumentException: Only one of (X-Auth-Token) or (X-Username, X-Api-Key/X-Password) headers should be present at a time and when giving X-Username only one of X-Api-Key or X-Password header should be present.] for HTTP GET /actuator/health
2021-05-27 21:11:50.611 DEBUG 87018 --- [ctor-http-nio-3] o.s.http.codec.json.Jackson2JsonEncoder : [dbf63e0b-1] Encoding [{timestamp=Thu May 27 21:11:50 IST 2021, path=/actuator/health, status=400, message=Only one of (X-A (truncated)...]
2021-05-27 21:11:50.656 DEBUG 87018 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations : [id: 0xdbf63e0b, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53830] Decreasing pending responses, now 0
2021-05-27 21:11:50.660 DEBUG 87018 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations : [id: 0xdbf63e0b, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53830] Last HTTP packet was sent, terminating the channel
2021-05-27 21:11:50.660 DEBUG 87018 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter : [dbf63e0b-1] Completed 400 BAD_REQUEST
2021-05-27 21:11:50.662 DEBUG 87018 --- [ctor-http-nio-3] r.n.http.server.HttpServerOperations : [id: 0xdbf63e0b, L:/[0:0:0:0:0:0:0:1]:8082 - R:/[0:0:0:0:0:0:0:1]:53830] Last HTTP response frame
You don't need to add the AuthenticationWebFilter and AuthorizationWebFilter manually in your configuration.
A more modern way to achieve what you want is usually doing like this:
#Bean
SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange((exchanges) -> exchanges
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated()
)
.csrf().disable();
return http.build();
}
You can find more information about the security configuration in the Spring Security docs

Spring Security + Keycloak: Accept Bearer Token

Somehow I'm lost with Spring Security and Keycloak.
In an application I successfully receive an access token from my Keycloak instance. I then use this token for a request against my Spring Security server (which uses the same Keycloak instance).
But all I get are 403 errors.
Here are code excerpts (written in kotlin):
Security Config:
#KeycloakConfiguration
abstract class MyConfig : KeycloakWebSecurityConfigurerAdapter() {
#Autowired
lateinit var keycloakClientRequestFactory: KeycloakClientRequestFactory
#Bean
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
fun keycloakRestTemplate(): KeycloakRestTemplate {
return KeycloakRestTemplate(keycloakClientRequestFactory)
}
#Autowired
#Throws(Exception::class)
fun configureGlobal(auth: AuthenticationManagerBuilder) {
val keycloakAuthenticationProvider = keycloakAuthenticationProvider()
keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(SimpleAuthorityMapper())
auth.authenticationProvider(keycloakAuthenticationProvider)
}
#Bean
fun KeycloakConfigResolver(): KeycloakConfigResolver {
return KeycloakSpringBootConfigResolver()
}
#Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http.csrf().disable()
.cors().and()
.authorizeRequests()
.anyRequest().authenticated()
http.requiresChannel().anyRequest().requiresSecure()
}
#Bean
override fun sessionAuthenticationStrategy(): SessionAuthenticationStrategy =
RegisterSessionAuthenticationStrategy(SessionRegistryImpl())
#Bean
fun keycloakAuthenticationProcessingFilterRegistrationBean(
filter: KeycloakAuthenticationProcessingFilter): FilterRegistrationBean {
val registrationBean = FilterRegistrationBean(filter)
registrationBean.isEnabled = false
return registrationBean
}
#Bean
fun keycloakPreAuthActionsFilterRegistrationBean(
filter: KeycloakPreAuthActionsFilter): FilterRegistrationBean {
val registrationBean = FilterRegistrationBean(filter)
registrationBean.isEnabled = false
return registrationBean
}
#Bean
fun corsConfigurationSource(): CorsConfigurationSource {
val configuration = CorsConfiguration()
configuration.allowedOrigins = arrayListOf("*").toMutableList()
configuration.allowedMethods = arrayListOf("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH","OPTIONS")
configuration.allowCredentials = true
configuration.allowedHeaders = arrayListOf("Authorization", "Cache-Control", "Content-Type")
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", configuration)
return source
}
}
In my controller:
#RequestMapping("/test")
#ResponseBody
fun test(): String {
return "success"
}
In my call to the server I can verify that the authorization header is set as follows: Authorization: Bearer [Token]
What am I missing? I'm glad for any help!
Edit:
Spring Security Debug Log:
2018-02-13 15:37:37.594 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /maintenance/secure-test; Attributes: [authenticated]
2018-02-13 15:37:37.594 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#9055286a: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#59b2: RemoteIpAddress: 192.168.1.4; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2018-02-13 15:37:37.595 DEBUG 13245 --- [io-10010-exec-3] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2018-02-13 15:37:37.595 DEBUG 13245 --- [io-10010-exec-3] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2018-02-13 15:37:37.595 DEBUG 13245 --- [io-10010-exec-1] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#6b79755c, returned: -1
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:124) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
[...skipping full stack trace...]
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']]
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/maintenance/secure-test'; against '/**/favicon.ico'
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager#40c8c1fa, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]]
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : httpRequestMediaTypes=[application/json, text/plain, */*]
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/json
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/json = true
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = false
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.util.matcher.AndRequestMatcher : Did not match
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.s.HttpSessionRequestCache : Request not saved as configured RequestMatcher did not match
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point.
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2018-02-13 15:37:37.596 DEBUG 13245 --- [io-10010-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2018-02-13 15:37:37.597 DEBUG 13245 --- [io-10010-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Keycloak debug (on Spring server):
2018-02-13 17:29:46.455 DEBUG 14194 --- [io-10010-exec-8] o.k.adapters.PreAuthActionsHandler : adminRequest [URI]/maintenance/secure-test
2018-02-13 17:29:46.455 DEBUG 14194 --- [io-10010-exec-8] .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /maintenance/secure-test
2018-02-13 17:29:46.455 DEBUG 14194 --- [io-10010-exec-8] o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke [URI]/maintenance/secure-test
2018-02-13 17:29:46.455 DEBUG 14194 --- [io-10010-exec-8] o.k.a.AuthenticatedActionsHandler : Policy enforcement is disabled.
2018-02-13 17:29:46.461 DEBUG 14194 --- [io-10010-exec-9] o.k.adapters.PreAuthActionsHandler : adminRequest [URI]/maintenance/secure-test
2018-02-13 17:29:46.462 DEBUG 14194 --- [io-10010-exec-9] .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /maintenance/secure-test
2018-02-13 17:29:46.462 DEBUG 14194 --- [io-10010-exec-9] o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke [URI]/maintenance/secure-test
2018-02-13 17:29:46.462 DEBUG 14194 --- [io-10010-exec-9] o.k.a.AuthenticatedActionsHandler : Policy enforcement is disabled.
2018-02-13 17:29:46.463 DEBUG 14194 --- [io-10010-exec-9] o.k.adapters.PreAuthActionsHandler : adminRequest [URI]/maintenance/secure-test
2018-02-13 17:29:46.463 DEBUG 14194 --- [io-10010-exec-9] f.KeycloakAuthenticationProcessingFilter : Request is to process authentication
2018-02-13 17:29:46.463 DEBUG 14194 --- [io-10010-exec-9] f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
2018-02-13 17:29:46.467 DEBUG 14194 --- [io-10010-exec-9] o.k.a.BearerTokenRequestAuthenticator : Verifying access_token
2018-02-13 17:29:46.572 DEBUG 14194 --- [io-10010-exec-9] o.k.a.rotation.JWKPublicKeyLocator : Realm public keys successfully retrieved for client service-api. New kids: [omitted KID]
2018-02-13 17:29:46.573 DEBUG 14194 --- [io-10010-exec-9] o.k.a.BearerTokenRequestAuthenticator : successful authorized
2018-02-13 17:29:46.577 DEBUG 14194 --- [io-10010-exec-9] a.s.a.SpringSecurityRequestAuthenticator : Completing bearer authentication. Bearer roles: []
2018-02-13 17:29:46.578 DEBUG 14194 --- [io-10010-exec-9] o.k.adapters.RequestAuthenticator : User ’test' invoking ‚[URI]/maintenance/secure-test' on client 'service-api'
2018-02-13 17:29:46.578 DEBUG 14194 --- [io-10010-exec-9] o.k.adapters.RequestAuthenticator : Bearer AUTHENTICATED
2018-02-13 17:29:46.578 DEBUG 14194 --- [io-10010-exec-9] f.KeycloakAuthenticationProcessingFilter : Auth outcome: AUTHENTICATED
2018-02-13 17:29:46.586 DEBUG 14194 --- [io-10010-exec-9] o.k.a.s.management.HttpSessionManager : Session created: [omitted sessione ID]
2018-02-13 17:29:46.588 DEBUG 14194 --- [io-10010-exec-9] f.KeycloakAuthenticationProcessingFilter : Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken#bb340ce7: Principal: test; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount#68bb9634; Not granted any authorities
2018-02-13 17:29:46.588 DEBUG 14194 --- [io-10010-exec-9] o.k.a.AuthenticatedActionsHandler : AuthenticatedActionsValve.invoke [URI]/maintenance/secure-test
2018-02-13 17:29:46.588 DEBUG 14194 --- [io-10010-exec-9] o.k.a.AuthenticatedActionsHandler : Policy enforcement is disabled.
For the sake of completion I answer this question:
Like stated in a comment on the question, the problem was the call to super.configure(http) in KeycloakWebSecurityConfigurerAdapter.
So, if you encounter a similar error check if you make this call. The config should look something like this:
#KeycloakConfiguration
class MyConfig : KeycloakWebSecurityConfigurerAdapter() {
// [...]
#Throws(Exception::class)
override fun configure(http: HttpSecurity) {
super.configure(http) // this call was missing
// [...]
}
}

Spring Security (Java Config): Using antmatchers for same URL with differing HTTP methods

I'm trying to restrict GET access to a URL for one role, and POST access to the same URL for another role as seen below.
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("readuser").password("password").roles("USER", "READ").and()
.withUser("admin").password("password").roles("USER", "READ", "WRITE");
}
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().permitAll().and()
.logout().permitAll().and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/foo").hasRole("READ")
.antMatchers(HttpMethod.POST, "/api/foo").hasRole("WRITE")
.anyRequest().authenticated()
.and().csrf().disable()
.httpBasic();
When I try a GET (or a POST) with my readuser account, I get an access denied error; but when I try either with the admin account, it can do both.
However, when I remove the line .antMatchers(HttpMethod.POST, "/api/foo").hasRole("WRITE") then my readuser account can properly hit /api/foo with a GET request.
How can I make Spring Security allow both of these restrictions?
UPDATE - including relevant spring security debug log information
Here are the relevant logs when attempting with readuser:
************************************************************
Request received for GET '/api/foo?id=foo':
Request(GET //localhost:8089/api/foo?id=foo)#b4603eb
servletPath:/api/foo
pathInfo:null
headers:
Authorization: Basic cnVudXNlcjpwYXNzd29yZA==
Cookie: JSESSIONID=node0fe3b0i44a5sbpohi6jq6dkkw0.node0
Cache-Control: no-cache
Accept: */*
User-Agent: PostmanRuntime/3.0.11-hotfix.2
Connection: keep-alive
Postman-Token: 99a23213-6cf8-4686-9886-7f9c2de13c6f
Host: localhost:8089
Accept-Encoding: gzip, deflate
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
.
.
.
2017-05-08 11:31:27.817 DEBUG 5812 --- [p1731685294-106] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/foo'; against 'GET'
2017-05-08 11:31:27.817 DEBUG 5812 --- [p1731685294-106] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/foo'; against '/api/foo'
2017-05-08 11:31:27.817 DEBUG 5812 --- [p1731685294-106] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/foo?id=foo; Attributes: [hasRole('ROLE_WRITE')]
2017-05-08 11:31:27.818 DEBUG 5812 --- [p1731685294-106] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken#a38eb23d: Principal: org.springframework.security.core.userdetails.User#5c7268d6: Username: readuser; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_READ,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_READ, ROLE_USER
2017-05-08 11:31:27.818 DEBUG 5812 --- [p1731685294-106] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#7b20c046, returned: -1
2017-05-08 11:31:27.819 DEBUG 5812 --- [p1731685294-106] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is not anonymous); delegating to AccessDeniedHandler
org.springframework.security.access.AccessDeniedException: Access is denied
.
.
.
2017-05-08 11:31:27.823 DEBUG 5812 --- [p1731685294-106] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
You are using the wrong HttpMethod class.
javax.ws.rs.HttpMethod#GET returns a String and therefore you use antMatchers(String... antPatterns) instead of antMatchers(HttpMethod method, String... antPatterns) in your Spring Security configuration.
With that configuration Spring Security checks against the URL patterns GET and /api/foo (both for all HTTP methods), see your log:
2017-05-08 11:31:27.817 DEBUG 5812 --- [p1731685294-106] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/foo'; against 'GET'
2017-05-08 11:31:27.817 DEBUG 5812 --- [p1731685294-106] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/foo'; against '/api/foo'
You have to use org.springframework.http.HttpMethod#GET, which returns a HttpMethod object.

Spring zuul proxy not accepting bearer token

I have a zuul proxy (http://localhost:8765) serving an angular web app (http://localhost:8080/app). Behind the zuul proxy there is also an oauth2 server (http://localhost:8899).
The web resources are proxied under http://localhost:8765/web and the resources are proxied under http://localhost:8765/api.
The Zuul proxy serves the static web resources without authentication. So the first authentication is done through a JSON call (GET /api/user) which of course fails with 401.
Now I forward the page to "http://localhost:8899/uaa/oauth/authorize?response_type=token&client_id=web&redirect_uri=http://localhost:8765/web/index.html" to make an implicit grant oauth 2 flow. I can authorize now the web application and get forwarded back to my web app. The token is part of the url and I can parse it.
IMHO the only thing I now have to do is to add this token as Authorization header (e.g. Authorization:Bearer 2829d5e2-4fbe-4f91-b74d-c99b2fe894a7). But the zuul proxy won't accept this request as authorized.
I am using spring boot 1.3.2 and spring cloud Brixton.M4.
The Zuul Server Application can be found here and the security config here.
Here are my request headers:
Accept:application/json
Accept-Encoding:gzip, deflate, sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Authorization:Bearer 2829d5e2-4fbe-4f91-b74d-c99b2fe894a7
Connection:keep-alive
Cookie:XSRF-TOKEN=a6ddea36-e3b7-4f22-b80c-b4c8b6fd7760; JSESSIONID=DAE4649D11386D586A0CF739148E505A; XSRF-TOKEN=3a7a57ad-68f6-4cc6-923b-4e8fe340fe1e
Host:localhost:8765
Referer:http://localhost:8765/web/index.html
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/48.0.2564.82 Chrome/48.0.2564.82 Safari/537.36
X-Auth-Token:2829d5e2-4fbe-4f91-b74d-c99b2fe894a7
X-Requested-With:XMLHttpRequest
X-XSRF-TOKEN:a6ddea36-e3b7-4f22-b80c-b4c8b6fd7760
My Zuul configuration is:
server:
context-path: /
security:
user:
password: none
oauth2:
sso:
loginPath: /login
client:
accessTokenUri: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth/token
userAuthorizationUri: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth/authorize
clientId: web
resource:
userInfoUri: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/user
preferTokenInfo: false
zuul:
routes:
web-portal:
path: /web/**
url: http://localhost:8080/app
user:
path: /api/user/**
url: ${authserver.protocol}://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/user
authentication-service:
path: /uaa/**
stripPrefix: false
---
spring:
profiles: local
logging:
level:
org:
springframework:
security: DEBUG
authserver:
protocol: http
hostname: localhost
port: 8899
contextPath: uaa
The zuul server log is:
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/api/user' matched by universal pattern '/**'
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2016-02-11 17:11:02.958 DEBUG 3242 --- [nio-8765-exec-4] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade#5571734d. A new one will be created.
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher#42c144ce
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using org.springframework.security.web.csrf.CsrfFilter$DefaultRequiresCsrfMatcher#4ad95822
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.util.matcher.AndRequestMatcher : Did not match
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 5 of 13 in additional filter chain; firing Filter: ''
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /api/user' doesn't match 'POST /logout
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 7 of 13 in additional filter chain; firing Filter: 'OAuth2ClientAuthenticationProcessingFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/login'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken#905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: DAE4649D11386D586A0CF739148E505A; Granted Authorities: ROLE_ANONYMOUS'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.security.web.FilterChainProxy : /api/user at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/index.html'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/home.html'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/web/**'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/user'; against '/uaa/oauth/**'
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/user; Attributes: [authenticated]
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken#905571d8: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails#0: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: DAE4649D11386D586A0CF739148E505A; Granted Authorities: ROLE_ANONYMOUS
2016-02-11 17:11:02.959 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter#77816ac4, returned: -1
2016-02-11 17:11:02.960 DEBUG 3242 --- [nio-8765-exec-4] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
How can I force the authentication on the zuul proxy against the access token?
--- Edit:
If I enable the authentication for the static web resource by removing the http security exception for it, I get forwarded to the authorization page. When the request gets forwarded back everything works. The zuul proxy forwards to the oauth server with its /login URL as return address. This seems to be the correct way. I suppose it saves some information in its session and after that forwards back to the initial requesting page (in my case /web/index.html).
When I now restart the authentication service (like simulating expired token) the resources from the web application are served, but the request to /api/user (proxied to the authentication server) is denied.
Same happens when I come from a manually constructed authorize URL like
http://localhost:8899/uaa/oauth/authorize?response_type=token&client_id=web&redirect_uri=http://localhost:8765/web/index.html. First I get to the authorization page of the oauth server. This is correct. On click on authorize the request gets forwarded to the web app (/web/index.html). All static content is served without problem, but access to /api/user is again denied. This time with an error logged in the oauth server: Invalid access token: dff5121b-06e4-4bd7-b48e-08ad82d71404
zuul api not forward header by default so disable it we need to add it
zuul:
sensitive-headers: Cookie,Set-Cookie
You should move to Spring Boot 1.3x.
Then, you can annotate you Zulu Proxy with #EnableOAuath2Sso annotation.
In your application.yml for Zuul, specify the following (for Spring Boot 1.3x):
security:
user:
password: none
oauth2:
client:
accessTokenUri: ${oauthserver}:${oauthport}/oauth/token
userAuthorizationUri: ${oauthserver}:${oauthport}/oauth/authorize
clientId: acme
clientSecret: acme secret
Thanks to #Dave I can answer my own question:
To have the Zuul proxy acception the OAuth Bearer Token header, you have to configure it as a resource server instead a SSO server.
Remove the #EnableOAuth2Sso annotation and use the #EnableResourceServer annotation instead. First I had still my WebSecurityConfigurerAdapter in place. So this was fixed by changing
#Configuration
#EnableOAuth2Sso
public class OAuthConfiguration extends WebSecurityConfigurerAdapter {
to
#Configuration
#EnableResourceServer
public class OAuthConfiguration extends ResourceServerConfigurerAdapter {
If one should use the implicit authentication is another topic (see comment from Dave).
By default the Zuul Proxy will remove certain headers because it deems them to sensitive and no other server should receive them. It has a list of cookies and headers it needs to remove. This needs to be overridden. The way to do this for a particular route is:
zuul:
routes:
profile-service-chaining:
sensitiveHeaders:
stripPrefix: false
serviceId: profile-service-chaining
path: /services/profiles
The line 'sensitiveHeaders:' will empty the cookies headers. This will cause all headers to be past to the server the request will be sent to. This will allow the Authorization header to sent to the target server. As the Zuul documentation says make sure to always remove sensitive headers. To do this the add:
sensitiveHeaders: Cookie
The above will remove the Cookie header before it is passed to the next server as specified by the Zuul route.

Resources