能否在Keycloak/Red Hat SSO中自定义Issuer URL?JWT验证异常求助
问题:Red Hat SSO生成的JWT Issuer不匹配导致容器化Spring Boot应用认证失败
我用本地Red Hat Single Sign-On(SSO)保护容器化的Spring Boot应用,认证依赖RH-SSO生成的JWT,但遇到Issuer(iss)字段无法被识别的问题。
为让容器内的Spring应用访问本地RH-SSO服务器,我在application.properties中配置了host.docker.internal:
spring.security.oauth2.resourceserver.jwt.issuer-uri= http://host.docker.internal:8888/auth/realms/MyRealm spring.security.oauth2.resourceserver.jwt.jwk-set-uri= http://host.docker.internal:8888/auth/realms/MyRealm/protocol/openid-connect/certs
相关日志显示JWT验证失败:
2023-08-31 01:36:25 2023-08-30 23:36:25.648 [http-nio-8080-exec-5] DEBUG o.s.security.web.FilterChainProxy - Securing POST /log/rest-log 2023-08-31 01:36:25 2023-08-30 23:36:25.660 [http-nio-8080-exec-5] DEBUG o.s.web.client.RestTemplate - HTTP GET http://host.docker.internal:8888/auth/realms/MyRealm/protocol/openid-connect/certs 2023-08-31 01:36:25 2023-08-30 23:36:25.661 [http-nio-8080-exec-5] DEBUG o.s.web.client.RestTemplate - Accept=[text/plain, application/json, application/*+json, */*] 2023-08-31 01:36:25 2023-08-30 23:36:25.859 [http-nio-8080-exec-5] DEBUG o.s.web.client.RestTemplate - Response 200 OK 2023-08-31 01:36:25 2023-08-30 23:36:25.860 [http-nio-8080-exec-5] DEBUG o.s.web.client.RestTemplate - Reading to [java.lang.String] as "application/json" 2023-08-31 01:36:28 2023-08-30 23:36:28.559 [http-nio-8080-exec-5] DEBUG o.s.s.oauth2.jwt.JwtClaimValidator - The iss claim is not valid 2023-08-31 01:36:28 2023-08-30 23:36:28.559 [http-nio-8080-exec-5] DEBUG o.s.s.o.s.r.a.JwtAuthenticationProvider - Failed to authenticate since the JWT was invalid
解码JWT后发现iss字段为"iss": "http://localhost:8888/auth/realms/MyRealm",和Spring配置的host.docker.internal不匹配,导致验证失败。请问能否在Keycloak/Red Hat SSO中自定义Issuer URL?
解决方案
方法1:在Red Hat SSO/Keycloak中自定义Issuer URL
可以直接在Realm级别配置自定义Issuer URL,步骤如下:
- 登录Red Hat SSO管理控制台,进入目标Realm(如
MyRealm) - 切换到**Realm Settings(领域设置)**标签页
- 找到**Frontend URL(前端URL)**配置项,填入期望作为Issuer的地址,比如
http://host.docker.internal:8888/auth/realms/MyRealm - 保存设置,重新生成的JWT的
iss字段会自动使用该配置的URL
注意:如果需要同时支持本地和容器内的访问场景,可考虑配置多个Issuer,或在Spring端做兼容处理。
方法2:在Spring Boot端兼容多Issuer
若不想修改Red Hat SSO的配置,可通过自定义JWT验证逻辑兼容多个Issuer:
创建自定义JwtDecoder Bean,替换默认验证逻辑,允许两个Issuer值同时通过校验:
@Bean public JwtDecoder jwtDecoder() { NimbusJwtDecoder jwtDecoder = NimbusJwtDecoder.withJwkSetUri("http://host.docker.internal:8888/auth/realms/MyRealm/protocol/openid-connect/certs").build(); OAuth2TokenValidator<Jwt> localIssuerValidator = new JwtIssuerValidator("http://localhost:8888/auth/realms/MyRealm"); OAuth2TokenValidator<Jwt> dockerIssuerValidator = new JwtIssuerValidator("http://host.docker.internal:8888/auth/realms/MyRealm"); OAuth2TokenValidator<Jwt> combinedValidator = OAuth2ValidatorUtils.combine(localIssuerValidator, dockerIssuerValidator); jwtDecoder.setJwtValidator(combinedValidator); return jwtDecoder; }
内容的提问来源于stack exchange,提问作者drakidou
相关产品推荐
相关产品推荐

