我们在Sping Boot 3.0.2上运行的项目在为特定客户端集成keycloak 10.0.2(3年前的版本)时遇到了问题。
下面是几个依赖项:
POM:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
application.properties :
spring.security.oauth2.client.registration.keycloak.client-id=client1
spring.security.oauth2.client.registration.keycloak.client-secret=xxxxx-xxxxx
spring.security.oauth2.client.registration.keycloak.client-name=keycloak
spring.security.oauth2.client.registration.keycloak.scope=profile,openid,email
spring.security.oauth2.client.registration.keycloak.redirect-uri=https://localhost:9097/login/oauth2/code/keycloak
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.keycloak.issuer-uri=http://localhost:8080/auth/realms/testrealm2
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/auth/realms/testrealm
Spring安全配置:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf()
.disable()
.authorizeHttpRequests()
.requestMatchers(getStaticResources(coralEnabled).toArray(new String[0]))
.permitAll()
.anyRequest()
.authenticated()
.and()
.oauth2Login()
.successHandler(kwAuthenticationSuccessHandler)
.failureHandler(kwAuthenticationFailureHandler)
.failureUrl("/login?error")
.loginPage("/login")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.addLogoutHandler(
new HeaderWriterLogoutHandler(
new ClearSiteDataHeaderWriter(
ClearSiteDataHeaderWriter.Directive.CACHE,
ClearSiteDataHeaderWriter.Directive.COOKIES,
ClearSiteDataHeaderWriter.Directive.STORAGE)));
return http.build();
}
@Bean
WebClient webClient(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrationRepository, authorizedClientRepository);
oauth2.setDefaultOAuth2AuthorizedClient(true);
return WebClient.builder().apply(oauth2.oauth2Configuration()).build();
}
@Bean
public AuthorizationRequestRepository<OAuth2AuthorizationRequest>
authorizationRequestRepository() {
return new HttpSessionOAuth2AuthorizationRequestRepository();
}
@Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest>
accessTokenResponseClient() {
DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient =
new DefaultAuthorizationCodeTokenResponseClient();
return accessTokenResponseClient;
}
密钥隐藏版本:10.0.2
Sping Boot Web应用程序是基于UI/Thymeleaf的。
当用户点击UI中的登录按钮时,在nimbus框架中失败:无效的json当尝试到剖析.
错误:
com.nimbusds.jwt.proc.BadJWTException: Payload of JWS object is not a valid JSON object
at com.nimbusds.jwt.proc.DefaultJWTProcessor.extractJWTClaimsSet(DefaultJWTProcessor.java:262) ~[nimbus-jose-jwt-9.24.4.jar!/:9.24.4]
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:352) ~[nimbus-jose-jwt-9.24.4.jar!/:9.24.4]
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:303) ~[nimbus-jose-jwt-9.24.4.jar!/:9.24.4]
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.createJwt(NimbusJwtDecoder.java:154) ~[spring-security-oauth2-jose-6.0.1.jar!/:6.0.1]
at org.springframework.security.oauth2.jwt.NimbusJwtDecoder.decode(NimbusJwtDecoder.java:137) ~[spring-security-oauth2-jose-6.0.1.jar!/:6.0.1]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.getJwt(OidcAuthorizationCodeAuthenticationProvider.java:245) ~[spring-security-oauth2-client-6.0.1.jar!/:6.0.1]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.createOidcToken(OidcAuthorizationCodeAuthenticationProvider.java:236) ~[spring-security-oauth2-client-6.0.1.jar!/:6.0.1]
at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:154) ~[spring-security-oauth2-client-6.0.1.jar!/:6.0.1]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-6.0.1.jar!/:6.0.1]
at org.springframework.security.authentication.ObservationAuthenticationManager.lambda$authenticate$1(ObservationAuthenticationManager.java:53) ~[spring-security-core-6.0.1.jar!/:6.0.1]
at io.micrometer.observation.Observation.observe(Observation.java:559) ~[micrometer-observation-1.10.3.jar!/:1.10.3]
at org.springframework.security.authentication.ObservationAuthenticationManager.authenticate(ObservationAuthenticationManager.java:52) ~[spring-security-core-6.0.1.jar!/:6.0.1]
其他oauth2集成,如Azure AD、Google,工作正常,但使用keycloak时,注意到解析令牌的一些问题。
经过一些调试后,我们注意到当标记合并时,有两个属性具有相同的名称“sub”,因此json无效。
{
"exp":1675788223,
"iat":1675787923,
"auth_time":1675787563,
"jti":"c07d2db2-xxxx",
"iss":"https://login.idm.xxx.com/auth/realms/appid-xxx",
"aud":"xxxx-dev",
"sub":"f:5ce9dxxxx:user@user.com",
"typ":"ID",
"azp":"xxxx-dev",
"nonce":"dH4EL-2zxxxx",
"session_state":"fc0a7xxxx",
"acr":"0",
"sub":"user@user.com",
"groups":[
"FGM-AuthUser",
"FGM-admin"
}
有人知道吗?
将keycloak 10.0.2(spring oauth2配置)与spring Boot 3.0.2集成,并期望身份验证无缝工作,但在nimbus令牌解析期间失败。
1条答案
按热度按时间k75qkfdt1#
这个特定的Keycloak版本已知存在JWT标记(https://issues.redhat.com/browse/KEYCLOAK-14309)中存在重复json密钥的问题。
JSON中的重复键在技术上是可能的(尽管绝对不推荐),因此您只能任由JWT解码器摆布。
不幸的是,NimbusJWT解码器对此非常严格,因为它会拒绝JSON
您的唯一选择是:
如果选择定制jwtDecoder路径,则需要在springsecurity上下文中注册定制解码器