I'm implementing single sign on authentication for Spring Boot application using OpenID Connect.I have configured Spring Boot Oauth2 client in my application with third party OpenID Connect authorization server. For Spring, I followed configuration this. My client, redirect uri are registered with the OpenID Provider. Using above configuration, when user tries to access any protected resource, the application redirects to auth server login page,wherein user submits login credentials.After this point my application fails with error
2021-08-20 17:26:07.481 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : HTTP POST https://{domain}/oauth2/token
2021-08-20 17:26:07.485 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : Accept=[application/json, application/*+json]
2021-08-20 17:26:07.487 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : Writing [{grant_type=[authorization_code], code=[BrHZBSzmXT4uvuUHfhyuhnyuhuh], redirect_uri=[https://{baseUrl}/login/oauth2/code/abc]}] as "application/x-www-form-urlencoded;charset=UTF-8"
2021-08-20 17:26:07.902 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : Response 200 OK
2021-08-20 17:26:07.905 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : Reading to [org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] as "application/json;charset=UTF-8"
2021-08-20 17:26:08.160 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : HTTP GET https://{domain}/oauth2/jwk/jwtotp
2021-08-20 17:26:08.162 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : Accept=[text/plain, application/json, application/*+json, */*]
2021-08-20 17:26:08.191 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : Response 200 OK
2021-08-20 17:26:08.191 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] o.s.web.client.RestTemplate : Reading to [java.lang.String] as "text/html;charset=UTF-8"
2021-08-20 17:26:08.215 DEBUG [dashboard,,,] 113904 --- [o-8443-exec-161] .s.o.c.w.OAuth2LoginAuthenticationFilter : Authentication request failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_id_token] An error occurred while attempting to decode the Jwt: Malformed Jwk set
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_id_token] An error occurred while attempting to decode the Jwt: Malformed Jwk set
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.createOidcToken(OidcAuthorizationCodeAuthenticationProvider.java:226) ~[spring-security-oauth2-client-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:155) ~[spring-security-oauth2-client-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter.attemptAuthentication(OAuth2LoginAuthenticationFilter.java:185) ~[spring-security-oauth2-client-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter.doFilterInternal(OAuth2AuthorizationRequestRedirectFilter.java:160) [spring-security-oauth2-client-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.29]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.29]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.29]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.29]
at com.sso.oidc.config.CORSFilter.doFilter(CORSFilter.java:37) [classes/:0.0.1-SNAPSHOT]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:9.0.29]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:9.0.29]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [catalina.jar:9.0.29]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:9.0.29]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) [catalina.jar:9.0.29]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [catalina.jar:9.0.29]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [catalina.jar:9.0.29]
at org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:555) [catalina.jar:9.0.29]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) [catalina.jar:9.0.29]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [catalina.jar:9.0.29]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [catalina.jar:9.0.29]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) [tomcat-coyote.jar:9.0.29]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-coyote.jar:9.0.29]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860) [tomcat-coyote.jar:9.0.29]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1591) [tomcat-coyote.jar:9.0.29]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:9.0.29]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_201]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_201]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.29]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]
Caused by: org.springframework.security.oauth2.jwt.JwtException: An error occurred while attempting to decode the Jwt: Malformed Jwk set
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.createJwt(NimbusJwtDecoder.java:155) ~[spring-security-oauth2-jose-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.decode(NimbusJwtDecoder.java:129) ~[spring-security-oauth2-jose-5.3.4.RELEASE.jar:5.3.4.RELEASE]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.createOidcToken(OidcAuthorizationCodeAuthenticationProvider.java:223) ~[spring-security-oauth2-client-5.3.4.RELEASE.jar:5.3.4.RELEASE]
... 61 common frames omitted
I'm not sure why this error happens, spring should be internally decoding the JWT token using the key recieved through jwk-set-uri. The logs don't have much information to provide.
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
SecurityConfig
@Configuration
@EnableWebSecurity
@Slf4j
//@Import(TrustStoreConfig.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/oauth2/**", "/login/**").permitAll().anyRequest().authenticated()
.and().oauth2Login().authorizationEndpoint()
.authorizationRequestRepository(new InMemoryRequestRepository()).and()
.successHandler(this::successHandler);
}
}
application.yml
logging:
level:
org.springframework.security.oauth2: DEBUG
org.springframework.web: TRACE
server:
port: 8443
spring:
security:
oauth2:
client:
provider:
abc:
authorization-uri: https://{domain}/oauth2/authorize
token-uri: https://{domain}/oauth2/token
user-info-uri: https://{domain}/oauth2/userinfo
user-name-attribute: sub
jwk-set-uri: https://{domain}/oauth2/jwk/jwtotp
registration:
abc:
authorization-grant-type: authorization_code
client-id: ****
client-secret: ***
scope: openid,email
redirect-uri: https://{baseUrl}/login/oauth2/code/abc
This is what my Spring Configuration looks like. I couldn't find much information regarding why this happens and how to resolve it. In this everything seems to be managed by Spring internally and there is no such mechanism to decode JWT. Please guide upon this.
I think you encountered an error setting your "authorization uri". Take a look. I believe the correct one would be; I hope I helped.