spring-boot - Spring Boot OAuth2/OpenID Connect Client 尝试解码 Jwt: Malformed Jwk set 时出错
问题描述
我正在使用 OpenID Connect 为 Spring Boot 应用程序实现单点登录身份验证。我已经在我的应用程序中使用第三方 OpenID Connect 授权服务器配置了 Spring Boot Oauth2 客户端。对于 Spring,我遵循配置this。我的客户重定向 uri 已向 OpenID 提供程序注册。使用上述配置,当用户尝试访问任何受保护的资源时,应用程序将重定向到身份验证服务器登录页面,用户在其中提交登录凭据。此后我的应用程序失败并出现错误
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
我不确定为什么会发生此错误,spring 应该使用通过 jwk-set-uri 接收的密钥在内部解码 JWT 令牌。日志没有提供太多信息。
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>
安全配置
@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);
}
}
应用程序.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
这就是我的 Spring 配置的样子。我找不到太多关于为什么会发生这种情况以及如何解决它的信息。在这一切似乎都由 Spring 在内部管理,并且没有这样的机制来解码 JWT。请对此进行指导。
解决方案
我认为您在设置“授权 uri”时遇到了错误。看一看。我相信正确的应该是;我希望我有所帮助。
...
.antMatchers("/oauth2/authorize**", "/oauth2/**" ..
推荐阅读
- python - 基于与目标变量的更高相关性,在彼此相关的那些特征中只保留一个特征
- ios - 对讲开启时无法从日历中选择日期
- java - 在 openSuse 上运行 Jar 文件时出现问题:java.io.FileNotFoundException(没有这样的文件或目录)
- r - 有没有办法使用 ggplot2/R 中的不同颜色为组中的一个特定变量着色?
- jenkins - Jenkins - 一次只能登录一个用户?
- azure - 适用于多种服务和环境的 Azure Pipelines 最佳实践
- azure - azure 数据工厂中的新功能/更改如何可用?
- r - 查找忽略 NA 的数据帧之间的协方差
- c# - 为什么我的错误突出显示不起作用?
- hibernate - java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: 意外令牌:> 第 1 行附近。没有得到原因