Обеспечение обслуживания с помощью KEYCLOAK - PullRequest
0 голосов
/ 06 мая 2020

Я вижу много тем по этому поводу, но кажется, что все они обращаются к KEYCLOAK с одним и тем же URL. Объяснение. Я пытаюсь настроить не фронтенд + микросервис, защищенный архитектурой K C. См. Рисунок: Simple architecture

Everything work well if keycloak (kc) is seen by everybody with the same url, that is for JS :

const keycloakURL = "http://test-kc-keycloak:8080/auth";

const keycloakParams = {
  url: keycloakURL,
  realm: "Test",
  clientId: "IHM"
};
const keycloak = Keycloak(keycloakParams);
...

For the service (project-default.yml):

thorntail:
  keycloak:
    secure-deployments:
      kc.war:
        auth-server-url: "http://test-kc-keycloak:8080/auth"
        realm: Test
        resource: service
        bearer-only: true
        ssl-required: external
  microprofile:
    jwtauth:
      realm: Test
      token:
        issuedBy: "http://test-kc-keycloak:8080/auth/realms/Test"


  logging:
    loggers:
      kc:
        level: DEBUG

See https://github.com/lbroque/test-kc

Но в реальном мире интерфейс находится на темной стороне net, а K C и служба предполагается находиться в защищенной среде. Таким образом, интерфейс видит K C через обратный прокси-сервер и схему HTTPS, тогда как служба видит его через схему HTTP.

Насколько я понимаю, служба пытается получить доступ к K C с SSL:

10:37:51,102 ERROR [adapters.rotation.JWKPublicKeyLocator] (default task-1) :
>>> Error when sending request to retrieve realm keys: org.keycloak.adapters.HttpClientAdapterException: IO error
    at org.keycloak.adapters.HttpAdapterUtils.sendJsonHttpRequest(HttpAdapterUtils.java:57)
    at org.keycloak.adapters.rotation.JWKPublicKeyLocator.sendRequest(JWKPublicKeyLocator.java:99)
    at org.keycloak.adapters.rotation.JWKPublicKeyLocator.getPublicKey(JWKPublicKeyLocator.java:63)
    at org.keycloak.adapters.rotation.AdapterTokenVerifier.getPublicKey(AdapterTokenVerifier.java:121)
    at org.keycloak.adapters.rotation.AdapterTokenVerifier.createVerifier(AdapterTokenVerifier.java:111)
    at org.keycloak.adapters.rotation.AdapterTokenVerifier.verifyToken(AdapterTokenVerifier.java:47)
    at org.wildfly.swarm.keycloak.mpjwt.deployment.KeycloakJWTCallerPrincipalFactory.parse(KeycloakJWTCallerPrincipalFactory.java:26)
    at org.wildfly.swarm.microprofile.jwtauth.deployment.auth.jaas.JWTLoginModule.validate(JWTLoginModule.java:100)
    at org.wildfly.swarm.microprofile.jwtauth.deployment.auth.jaas.JWTLoginModule.login(JWTLoginModule.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
    at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
    at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
    at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
    at org.jboss.security.authentication.JBossCachedAuthenticationManager.defaultLogin(JBossCachedAuthenticationManager.java:406)
    at org.jboss.security.authentication.JBossCachedAuthenticationManager.proceedWithJaasLogin(JBossCachedAuthenticationManager.java:345)
    at org.jboss.security.authentication.JBossCachedAuthenticationManager.authenticate(JBossCachedAuthenticationManager.java:323)
    at org.jboss.security.authentication.JBossCachedAuthenticationManager.isValid(JBossCachedAuthenticationManager.java:146)
    at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verifyCredential(JAASIdentityManagerImpl.java:123)
    at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verify(JAASIdentityManagerImpl.java:96)
    at org.wildfly.swarm.microprofile.jwtauth.deployment.auth.JWTAuthMechanism.authenticate(JWTAuthMechanism.java:77)
    at org.wildfly.extension.undertow.security.jaspi.modules.HTTPSchemeServerAuthModule.validateRequest(HTTPSchemeServerAuthModule.java:88)
    at org.jboss.security.auth.message.config.JBossServerAuthContext.invokeModules(JBossServerAuthContext.java:157)
    at org.jboss.security.auth.message.config.JBossServerAuthContext.validateRequest(JBossServerAuthContext.java:135)
    at org.jboss.security.plugins.auth.JASPIServerAuthenticationManager.isValid(JASPIServerAuthenticationManager.java:115)
    at org.wildfly.extension.undertow.security.jaspi.JASPICAuthenticationMechanism.authenticate(JASPICAuthenticationMechanism.java:125)
    at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:245)
    at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:231)
    at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:125)
    at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:99)
    at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:92)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    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.wildfly.extension.undertow.security.jaspi.JASPICSecureResponseHandler.handleRequest(JASPICSecureResponseHandler.java:48)
    at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
    at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1504)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
    at org.apache.http.conn.ssl.SSLSocketFactory.createLayeredSocket(SSLSocketFactory.java:573)
    at org.keycloak.adapters.SniSSLSocketFactory.createLayeredSocket(SniSSLSocketFactory.java:114)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:557)
    at org.keycloak.adapters.SniSSLSocketFactory.connectSocket(SniSSLSocketFactory.java:109)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:414)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445)
    at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
    at org.keycloak.adapters.HttpAdapterUtils.sendJsonHttpRequest(HttpAdapterUtils.java:36)
    ... 72 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
    at sun.security.validator.Validator.validate(Validator.java:262)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
    ... 94 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
    ... 100 more

означает, что он пытается использовать схему https, нет? поэтому я предполагаю, что он использует URL-адрес, найденный в ТОКЕНЕ, отправленном интерфейсом, который получил его со схемой HTTPS, потому что я настроил свою службу (поэтому она должна использовать схему HTTP):

thorntail:
  keycloak:
    secure-deployments:
      model4xxx.war:
        auth-server-url: "http://keycloak.hnr:9090/auth"
        realm: xxx
        resource: model4xxx
        bearer-only: true
        ssl-required: external
  microprofile:
    jwtauth:
      realm: xxx
      token:
        issuedBy: "http://keycloak.hnr:9090/auth/realms/xxxx"

Последний пункт: K C находится в контейнере DOCKER. Я пробовал несколько комбинаций переменных окружения KEYCLOAK_FRONTEND_URL, KEYCLOAK_HOSTNAME. Похоже, это не имеет никакого эффекта.

Думаю, я не понял цель auth-server-url. Что толку, если информацию можно найти в токене ????

Я уверен, что это что-то очень очевидное, чего я не вижу или не понимаю ... пожалуйста, помогите.

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Вы не можете получить доступ к экземпляру Keycloak как через HTTP, так и через HTTPS (или разные URL-адреса) для клиентов в одной и той же области. auth-server-url, принадлежащий эмитенту токена, должен быть одинаковым, это проверяется разными адаптерами .

ЭТО, ПОКАЗЫВАЕТСЯ, ДО ТОГО, КАК ВЕРСИЯ KEYCLOAK 8, ОДНАКО

Кажется, ваш вопрос отражен в этом билете JIRA , и у команды Keycloak есть решение для этого, которое задокументировано в этом черновике и здесь . Вероятно, вы можете немного настроить изображение keycloak docker и добавить эту конфигурацию, поэтому подумайте, заслуживает ли оно того, чтобы вы это делали или обращались к серверу Keycloak извне из вашей службы.

См. Также:

0 голосов
/ 06 мая 2020

Шампанское! С этим conf (project-defauls.yml):

thorntail:
  keycloak:
    secure-deployments:
      model4geo3d.war:
        auth-server-url: "http://keycloak.hnr:9090/auth"
        realm: xxxx
        resource: model4xxx
        bearer-only: true
        ssl-required: external
  microprofile:
    jwtauth:
      realm: xxx
      token:
        issuedBy: "https://keycloak.hnr/auth/realms/xxxx"

И:

       - "KEYCLOAK_FRONTEND_URL=https://keycloak.hnr/auth/"
        - "PROXY_ADDRESS_FORWARDING=true"

in docker - составьте контейнер keycloak (keycloak.environment)

И

keytool -import -trustcacerts -keystore /etc/ssl/certs/java/cacerts -storepass 'changeit' -file /home/core/dota/keycloak.hnr.crt -alias keycloak

в контейнере службы данных, отлично работает.

2020-05-06 17:41:56,582 INFO  [org.keycloak.adapters.KeycloakDeployment] (default task-1) Loaded URLs from http://keycloak.hnr:9090/auth/realms/xxxx/.well-known/openid-configuration

получил правильную конфигурацию, которую можно было использовать:)

Спасибо Xtreme Biker за его помощь и время.

...