我正在编写后端微服务,它接收来自前端的请求,其中包含Authorisation: Bearer ...
从 keycloak(在 docker 容器内)获得的令牌。
我从领域设置的 Keys 部分获得了 RSA 公钥来验证该令牌的签名,但似乎当带有 keycloak 的容器重新启动时,它会重新生成一对密钥,并且我在服务配置中设置的公钥变得无效。
从keycloak使用RSA公钥的正确方法是什么?有没有办法将它配置为使用一对固定的密钥对领域?领域导出时是否导出密钥?或者我必须使用 url like 从 keycloak 获取公钥http://keycloak:8080/auth/realms/:realm_name:
,我宁愿不这样做,因为这会增加 keycloak 和后端之间的依赖关系。
您应该根据颁发者身份服务器的/.well-known/jwks
端点验证 JWT 令牌的签名。
1) 查询颁发者身份服务器的/.well-known/jwks
端点(JWKS 代表 JSON Web Key Set)
2) 从 JWKS 获取与我们正在验证kid
的Bearer
令牌具有相同(密钥 ID)的 JWK(JSON Web 密钥)。要从kid
您的 JWT 令牌中获取 ,请首先使用jwt.io的调试器工具对其进行解码。
3)只要身份服务器颁发的令牌通过非对称加密算法(例如:RS256)进行验证,我们就可以仅使用公钥验证签名(因此您不需要私钥)
4) 可以从 JWK 中检索公钥(它是x5c
JWK JSON 中的条目)
5)Bearer
使用此公钥验证 JWT令牌的签名。
例如,在 Java 中,您可以这样验证:
// verify JWT signature based on Access Identity's JWKS RSA public key (RS256)
try {
Jwk jwk = new UrlJwkProvider(new URL(issuer + Constants.JWKS_ENDPOINT)).get(decodedJWT.getKeyId());
final PublicKey publicKey = jwk.getPublicKey();
if (!(publicKey instanceof RSAPublicKey)) {
throw new IllegalArgumentException("Key with ID " + decodedJWT.getKeyId() + " was found in JWKS but is not a RSA-key.");
}
Algorithm algorithm = Algorithm.RSA256((RSAPublicKey) publicKey, null);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer(issuer)
.build(); //Reusable verifier instance
verifier.verify(bearerToken);
LOGGER.info("Token verified!");
} catch (Exception e) {
LOGGER.error(e.getMessage());
throw new InvalidAccessTokenException("JWTVerificationException - Invalid token signature.");
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6705 次 |
最近记录: |