java - 如何使用 java 验证由 keycloak 签名的 JWT
问题描述
我有 keyCloack 生成的 JWT,RS256 类似这样
样本:
eyJhbGciOwia2lkIiA6ICJtSG1lajZEc09GaV9MejdSMjhzWjdMWkxBRXVzIn0.eyBzA2MzQvOTcwNjM1L1NNUyIsIi83Ni83NS9TTVMiXSwicHJYW1lIjoidGVzdDEwNUB1c2VyLmNvbSIsInVzZXJOYW1lIjoidGVzdDEwNUB1c2VyLmNvbSIsInVzZXJJZCI6IjU4NDM2NmQ4LWU5NDItNGJhNy04OGVlLWMyZTBlODhmZmY5ZCIsImVtYWlsIjoidGVzdDEwNUB1c2VyLmNvbSJ9.4TgC1MLyUl1P36oD6FafBCh0peEaCBmkyLheVjnlBu8uePl9xgEN6wdeWe
我需要使用密钥锁证书解码和验证这个令牌。
我可以通过 api 获得密钥锁证书。
https://xxx.xxx.com.tr/auth/realms/myrealm/protocol/openid-connect/certs
在响应中,我有 x5c 字段。
{
"keys": [
{
"kid": "j6DsCpPOz1RXJhtPR28sZ7LZLAEus",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "m0oTFvyLhLGIciXfndxc7uhIKE2-q9nJQKByd0FVYe8Cd4CHDpTzzcYdPWRR-1_VKQ75wqpybRt-LnnTKPNCXrPtPDRn2GFihtYyyO8VjeVtnz-iYJJAHkdp25HlMtX9l-VjnQX9s70-lbMmCVCRTerw",
"e": "AQAB",
"x5c": [
"MIICnTCCAYUCBgFzh2ZkQzANBgkqhkiG9w0BAQ50F/bO9PpWzJglQkU3q8CAwEAATANBgkqhkiG9w01faO/9ZzyiLMLsorUKzYPNAxc7Q9rLE0J2MCWfapx3/E4yyNjISuB1HpS5iF44OEhGHJlw7JQeogcZat0enB8yyXtP/cgBhCnrWwfugX8rHsWfHakBGdsoazR9w=="
],
"x5t": "YF6LE97opzsTtD-yLNx9-Lo",
"x5t#S256": "SdNCfMbCjvcq-JY3iiGAj7De9Hal_0Cck-bDFK3Ow"
}
]
}
如果我将 x5c 部分放在 ----CERTIFICATE----- 标记中,我可以通过https://jwt.io/验证这个 jwt
-----BEGIN CERTIFICATE-----
MIICnTCCAYUCBgFzh2ZkQzANBgkqhkiG9w0BAQ50F/bO9PpWzJglQkU3q8CAwEAATANBgkqhkiG9w01faO/9ZzyiLMLsorUKzYPNAxc7Q9rLE0J2MCWfapx3/E4yyNjISuB1HpS5iF44OEhGHJlw7JQeogcZat0enB8yyXtP/cgBhCnrWwfugX8rHsWfHakBGdsoazR9w==
-----END CERTIFICATE-----
如何在 Java 中验证相同的内容?
我尝试了几件事,但失败了。
解决方案
我找到了方法。
首先,我们需要登录 keycloack 控制台,您可以访问与领域相关的公钥。
现在你有来自 keycloak 的 publickey 和来自用户的 JWT。
您需要先导入相关库。
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
之后这是逻辑。
String token = "ghfghfdhdhdfhdfghdhdfhdfhdfhhdf";
String rsaPublicKey = "awdasdsadaefafafaef5df65d4f";
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(rsaPublicKey));
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey = kf.generatePublic(keySpec);
我们有公钥,我们需要验证它
Jws<Claims> jwt = null;
try {
jwt = Jwts.parserBuilder()
.setSigningKey(publicKey)
.build()
.parseClaimsJws(token);
} catch (Exception e) {
// if you get error, that means token is invalid.
}
推荐阅读
- pyspark - 在 PySpark 中,如何对字符串类型的 ID 进行哈希处理并将其转换为小于 365 的整数?
- matlab - 从某一行开始逐列替换值
- cloudera - CDH 6.2 - 添加新主机错误:dpkg-query: no packages found matching cloudera-manager-agent
- java - 在不将十进制转换为科学计数法的情况下将 JSON 转换为 XML
- asp.net-mvc - 安装 Visual Studio Build Tools 2017 时没有“ASP.NET MVC 4”程序集
- html - 如何防止元素绝对位置在css中重叠
- angular - 哪一个提供更好的性能和正确的方法来绑定@Input Angular?
- laravel - 请求的资源 laravel 5.8.8 上没有“Access-Control-Allow-Origin”标头
- wordpress - 如何优化使用 Revolution Slider、Elementor 构建的 WordPress 网站以及如何提高 PageSpeed 分数?
- angular - 基于 Laravel 和 Angular 组件的网站