Не нашли publicKey для ребенка, Keycloak?

Я получаю это исключение «Не нашел publicKey для ребенка» при вызове конечной точки из angular 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)

person Ahmed Gamal    schedule 09.06.2017    source источник
comment
Можете ли вы проверить свой keycloak.json и какую версию keycloak вы используете. В версии 2.4.0 (и, возможно, выше) открытый ключ не добавляется в json по умолчанию. Вам нужно скопировать его из основного царства в настройках царства -> ключи   -  person Anunay    schedule 05.02.2018
comment
@Анунай Спасибо! очень много. Это сработало :-)   -  person Магнайбаяр Ганз&    schedule 28.06.2019


Ответы (5)


Если это еще актуально, у меня была такая же проблема. В моем случае проблема заключалась в том, что в Keycloak неправильно настроено имя клиента. После исправления имени клиента в Keycloak все отлично работает.

person buderu    schedule 04.02.2018
comment
Вы можете быть более конкретным? - person Tiago Santos; 19.10.2018
comment
Можете ли вы указать больше? Была ли ваша ошибка типом client_id или чем-то еще? - person Menuka Ishan; 23.01.2019
comment
что ты сделал? Как этот ответ получает так много голосов? Это буквально не дает никакого ответа - person Long Nguyen; 30.03.2020
comment
У меня была та же проблема, и у меня была опечатка в client_id, объявленной в моих переменных среды API. Думаю, то же самое было и с @buderu. @LongNguyen проверьте правильность всей вашей конфигурации. - person HasBert; 27.07.2020

Я полагаю, что @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
person unelunatriste    schedule 11.05.2020

По моему опыту, обычно проблема заключается в том, что клиентское приложение не может получить доступ к jwks_uri конечным точкам сервера keycloak.

Вы можете исключить это, явно указав «открытый-ключ области», который будет «жестко кодировать» значение. 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

person Phillip Fleischer    schedule 12.05.2020

Это также может быть вызвано использованием неправильного токена для аутентификации.

Маркер идентификатора подписан с помощью HS256 (HMAC), а маркер доступа использует RS256 (RSA). Использование токена идентификатора вместо токена доступа может вызвать сообщение об ошибке, указанное выше.

person ojathelonius    schedule 29.09.2020

В моем случае эта проблема была вызвана старыми вкладками или окнами браузера. В частности, я часто перезапускаю свое приложение, не закрывая вкладку/окно, в котором работал внешний интерфейс. В результате новый экземпляр приложения, работающего с новым экземпляром Keycloak, открывает новую вкладку браузера, но продолжает получать запросы из старой вкладки/окна, что дает старый токен носителя. Ошибка перестает появляться в журналах после закрытия этих вкладок и окон. Хотя это тривиально, это довольно легко пропустить.

person João Matos    schedule 27.04.2021