在 Spring Boot 中使用 Keycloak 实现 JWT、JWE 和 JWS(签名 JWT)
Posted
技术标签:
【中文标题】在 Spring Boot 中使用 Keycloak 实现 JWT、JWE 和 JWS(签名 JWT)【英文标题】:Implementing JWT, JWE and JWS (signed JWT) with Keycloak in Spring Boot 【发布时间】:2018-03-27 14:15:50 【问题描述】:我尝试使用 Spring Boot 和 Keycloak 作为 AuthService 实现一个简单的 OAuth2“带有签名 JWT 的客户端身份验证”演示应用程序。
想法是:
-
一个安全的 REST 服务“生产者”
为角色为“read_person”的所有用户/主体提供端点 GET /person
为角色为“write_person”的所有用户/主体提供端点 POST /person
另一个(不安全的)REST 服务“消费者”
提供对所有人开放的 enpoint /api
通过
Feign
client 调用内部“生产者”,使用 RequestInterceptor 传递 AccessToken(签名的 JWT / JWS)
我阅读了有关文档:
http://www.keycloak.org/docs/latest/securing_apps/topics/oidc/java/client-authentication.html
说:
一旦客户端应用程序启动,它允许使用http://myhost.com/myapp/k_jwks 等URL 以JWKS 格式下载其公共> 密钥,>假设http://myhost.com/myapp 是您的客户端> 应用程序的基本URL。这个 URL 可以被 Keycloak 使用(见下文)。
在身份验证期间,客户端生成一个 JWT 令牌并使用 >其私钥对其进行签名,然后在 client_assertion >参数中的特定反向通道 >request(例如,代码到令牌请求)中将其发送到 Keycloak。
我在谷歌上搜索了很多关于这个主题的教程/演示或文档,但到目前为止都失败了。 所以这里是我的问题:
如何实现这个“k_jwk”端点?我是否可以自己在“制作人”中简单地构建一个@RestController
?如何配置 Keycloak 以了解此 URL?
如何实现我的“消费者”以从 Keycloak 获取新签名的 JWT?
更新 删除了恼人的 PS 声明。
【问题讨论】:
既然我们已经在 Spring Boot Adapter 中实现了,为什么还要重新实现所有这些? 请在这里告诉我如何使用 Keycloak 适配器。我找不到任何演示或文档。 keycloak.org/docs/latest/securing_apps/topics/oidc/java/… ,请查看我的博文developers.redhat.com/blog/2017/05/25/… 或我们的快速入门github.com/keycloak/keycloak-quickstarts 我在您的博客或这些快速入门中找不到任何有关使用签名 JWT 的文档。 好吧,它没有记录,因为它是在内部完成的,如果你使用适配器,你不必关心这个,如果你想重新实现我们的适配器所做的检查 Keycloak 项目的源代码。 【参考方案1】:您不需要实现 k_jwk 端点,这是由适配器处理的。默认情况下,Keycloak 将查看 http:///your.app.com/k_jwk
(但如果需要,您可以在控制台中覆盖它)。
然后你需要配置你的 Spring Boot 客户端,只需使用与 keycloak.json 相同的属性,但格式为 application.properties:
...
keycloak.credentials.jwt.client-keystore-file=classpath:keystore-client.jks keycloak.credentials.jwt.client-keystore-type=JKS
等等……
您需要一个令牌来调用producer
,但正如您所说,入口点将是一个不安全的端点,因此您可能希望为此使用Service Account。
我希望这会有所帮助。
【讨论】:
好的,谢谢。第一个信息非常方便。我将尝试理解并实施此服务帐户主题。 我可能需要进一步的帮助。我使用正确的 keycloak 设置和 gradle 依赖项中的适配器设置了一个客户端应用程序。我创建了一个 Feign 客户端(RestTemplate 对我来说也可以)。怎么办?如何生成 JWT?我不明白服务帐户的提示。文档说:keycloak.org/docs/2.5/server_admin/topics/clients/oidc/… 总结:通过 POST /auth/realms/demo/protocol/openid-connect/token 从 keycloak 获取令牌,所以我必须自己写这个? 是的,如果您想使用签名的 JWT 作为客户端身份验证,可能需要做一些手动工作,但您可以利用此类获取 jwt 令牌github.com/keycloak/keycloak/blob/master/adapters/oidc/…【参考方案2】:更新
我无法解决这个问题,但同时学到了一些关于singned JWT的东西:
通过自己创建一个包含所有必要声明(sub、nbf、exp ...)的 Json 结构并使用来自 Keycloak 的 JKS/私钥对其进行签名/认证,从而创建一个所谓的“不记名令牌”。 Keycloak 旁边有一些不错的第三方库可以做到这一点。
要从 Keycloak 获取真正的 AccessToken (JWE/JWS):在 /auth/realms/$realm/protocol/openid-connect/token/introspect 处将此静态最终承载令牌发送到 Keycloak em>
使用查询参数:
grant_type=client_credentials&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=$BEARER_TOKEN
-
使用接收到的真实AccessToken访问ResourceServer...
【讨论】:
我有一个类似的问题,所以你能展示一段代码来使用 jwt 和 spring boot 从 keycloak 获取令牌吗?请.. PS如果你想要这是我的问题:https://***.com/questions/49900124/can-i-pass-a-principal-with-rest-template-if-im-using-an-async-task-wiht-spring以上是关于在 Spring Boot 中使用 Keycloak 实现 JWT、JWE 和 JWS(签名 JWT)的主要内容,如果未能解决你的问题,请参考以下文章
Grails、Spring Security 和 Keycloak:表单以 ISO-8859-1 而不是 UTF-8 提交
spring-boot实战12:Spring Boot中使用JavaMailSender发送邮件
Spring Boot:在Spring Boot中使用Mysql和JPA
在 spring-boot 项目中使用 spring mvc xml 项目