我在从角度 js 2 调用端点到 widlfly 服务器时收到此异常"找不到孩子的公钥"。
身份验证发生在 KeyCloak 中,但是我使用相同的令牌从同一领域的不同客户端(不同的微服务(调用大约 8 个端点,但我只为此微服务调用收到此异常。
我确定用户具有所有客户端的所有角色。 我还在 JWT 上解码了令牌以验证这一点。
有时有效,有时无效!!这是异常堆栈跟踪:
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:90)
at sun.security.validator.Validator.getInstance(Validator.java:179)
at sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:312)
at sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:171)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:184)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
... 55 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:88)
... 67 more
2017-06-09 00:33:35,994 ERROR [org.keycloak.adapters.rotation.AdapterRSATokenVerifier] (default task-445) Didn't find publicKey for kid: QSm64gYAxG5-5Lt5r-T2dqQmHb8KKJ2dL3h_3Y8zXBE
2017-06-09 00:33:35,994 ERROR [org.keycloak.adapters.BearerTokenRequestAuthenticator] (default task-445) Failed to verify token: org.keycloak.common.VerificationException: Didn't find publicKey for specified kid
at org.keycloak.adapters.rotation.AdapterRSATokenVerifier.getPublicKey(AdapterRSATokenVerifier.java:47)
at org.keycloak.adapters.rotation.AdapterRSATokenVerifier.verifyToken(AdapterRSATokenVerifier.java:55)
at org.keycloak.adapters.rotation.AdapterRSATokenVerifier.verifyToken(AdapterRSATokenVerifier.java:37)
at org.keycloak.adapters.BearerTokenRequestAuthenticator.authenticateToken(BearerTokenRequestAuthenticator.java:87)
at org.keycloak.adapters.BearerTokenRequestAuthenticator.authenticate(BearerTokenRequestAuthenticator.java:82)
at org.keycloak.adapters.RequestAuthenticator.authenticate(RequestAuthenticator.java:67)
at org.keycloak.adapters.undertow.AbstractUndertowKeycloakAuthMech.keycloakAuthenticate(AbstractUndertowKeycloakAuthMech.java:110)
at org.keycloak.adapters.undertow.ServletKeycloakAuthMech.authenticate(ServletKeycloakAuthMech.java:92)
at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:233)
at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:250)
at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:219)
at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:121)
at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:96)
at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:89)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)
at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.keycloak.adapters.undertow.ServletPreAuthActionsHandler.handleRequest(ServletPreAuthActionsHandler.java:69)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
如果这仍然相关,我遇到了同样的问题。就我而言,问题是在Keycloak中客户端名称配置不正确。在Keycloak中更正客户端名称后,一切正常。
根据我的经验,这通常是客户端应用程序无法访问 keycloak 服务器的jwks_uri
端点的问题。
您可以通过显式指定"领域公钥"来排除这种情况,这将"硬编码"值。 https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/java/java-adapter-config.adoc
您还可以终端进入应用程序容器,并确保可以卷曲这些端点。 请务必验证这是否与适配器中的身份验证服务器配置匹配。
http://localhost:8080/auth/realms/master/protocol/openid-connect/certs
http://localhost:8080/auth/realms/master/protocol/openid-connect/certs
这也可能是由于使用错误的令牌进行身份验证造成的。
ID 令牌使用HS256 (HMAC( 签名,而访问令牌使用 RS256 (RSA( 进行签名。使用 ID 令牌而不是访问令牌可能会导致上述错误消息。
@buderu的意思是,您必须确保应用程序上的领域和客户端配置与Keycloak上的配置相匹配。正如@Anunay评论的那样,根据您的Keycloak版本,您需要指定您的公钥。
请注意,如果客户端仅是持有者,则需要提供其机密。
我的配置(Keycloak v6.0.1(是这样的:
keycloak:
realm: master
auth-server-url: http://127.0.0.1:8080/auth
resource: my-client-name
bearer-only: true
credentials:
secret: 3892g8m5-0c5e-498e-95v1-330q970b22e7
# Keycloak Enable CORS
cors: true
就我而言,此问题是由旧的浏览器选项卡或窗口引起的。更具体地说,我经常在不关闭运行前端的选项卡/窗口的情况下重新启动我的应用程序。因此,运行 Keycloak 新实例的应用程序的新实例会打开一个新的浏览器选项卡,但会不断接收来自旧选项卡/窗口的请求,从而生成旧的持有者令牌。关闭这些选项卡和窗口后,错误将停止出现在日志中。虽然这是微不足道的,但很容易错过。
就我而言,由于我放置了暂存服务器令牌,因此发生了身份验证错误。当我在生产环境中应用令牌时,错误消失了。很有可能是颁发的 jwt 令牌有问题。