Keycloak:缺少领域 public 密钥

Keycloak: missing realm public key

当我访问 keycloak 管理控制台(!远程)并创建客户端时:

密钥斗篷 OIDC JSON 没有 public 密钥

我希望在 JSON 中有这样的东西:

 "realm-public-key": "MIIBIjANBg....

我仍然不知道为什么 keycloak OIDC JSON 中没有 public 密钥(可能出于安全原因),但我在以下位置找到了它:

领域设置 > 键 > Public 键视图

keycloak.json 在最新的 keycloak 中没有任何领域 public 密钥...实际上您使用的是 keycloak 版本 2。3.x 它有一些变化。基本上,您可以为一个领域轮换多个 public 键。该文件说:-

In 2.3.0 release we added support for Public Key Rotation. When admin rotates the realm keys in Keycloak admin console, the Client Adapter will be able to recognize it and automatically download new public key from Keycloak. However this automatic download of new keys is done just if you don’t have realm-public-key option in your adapter with the hardcoded public key. For this reason, we don’t recommend to use realm-public-key option in adapter configuration anymore. Note this option is still supported, but it may be useful just if you really want to have hardcoded public key in your adapter configuration and never download the public key from Keycloak. In theory, one reason for this can be to avoid man-in-the-middle attack if you have untrusted network between adapter and Keycloak, however in that case, it is much better option to use HTTPS, which will secure all the requests between adapter and Keycloak.

我最初遇到了同样的问题,但后来发现我用错了 URL。 OpenID 配置由 Keycloak 根据标准 URL 发布:

http://localhost:8080/auth/realms/myrealm/.well-known/openid-configuration

但是public密钥发布在jwks_uri下,就是这样:

http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/certs

使用第二个 URL,使用 connect2id 库 (https://connect2id.com/products/nimbus-jose-jwt/examples/validating-jwt-access-tokens) 验证 JWT 非常容易:

...
JWT idToken = JWTParser.parse(bearerAccessToken.toString());

Nonce expectedNonce = null;
Issuer iss = new Issuer("http://localhost:8080/auth/realms/myrealm");
JWSAlgorithm jwsAlg = JWSAlgorithm.RS256;
URL jwkSetURL = new URL("http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/certs");

IDTokenValidator validator = new IDTokenValidator(iss, clientID, jwsAlg, jwkSetURL);
IDTokenClaimsSet claims = validator.validate(idToken, expectedNonce);
...