0

I have two Docker containers:

  1. RedHat Keycloak Server (https://keycloak.some.domain.com)
  2. Springboot app (http://localhost:8081)

In my Springboot app, I have defined a secure page at: http://localhost:8081/api/sample.json

Now, when I hit that endpoint, I am redirected to the correct login page and, if I submit the correct login/password credentials, I get the following 403 error (forbidden) page:

introducir la descripción de la imagen aquí

However, if I run the Springboot app directly, without a docker wrapper, like this:

java -jar app.jar

then, when I hit the same protected endpoint, I am redirected to the correct login page and, if I submit the correct login/password credentials, in this case, I get the CORRECT, expected page/response !!! (it is the same app !!!)

Given this scenario, I have started the dockerized Springboot app, went inside of the container with:

docker exec -it app bash

and then intalled lynx like this:

apt-get install lynx

from there, I did hit the protected endpoint locally:

lynx http://localhost:8081/api/sample.json

But I got exactly the same error page (403) error. So, I believe the problem is the docker wrapper, not the app. That is critical, because it means that this kind of behavior between keycloak and ANY dockerized app will be similar. :(

As a conclusion, if I execute "docker run -d -p 8081:8081 springboot-app-image", everything works perfectly except authentication process against keycloak (outside and inside the container).

From the Springboot app logs I can see this error trace when I hit the dockerized endpoint:

2020-03-17 15:29:19.503  INFO 1 --- [           main] com.example.app.MainApp            : Started MainApp in 13.257 seconds (JVM running for 14.845)
2020-03-17 15:29:30.139 DEBUG 1 --- [nio-8081-exec-1] o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8081/api/sample2.json
2020-03-17 15:29:30.169 DEBUG 1 --- [nio-8081-exec-1] o.k.a.a.ClientCredentialsProviderUtils   : Using provider 'secret' for authentication of client 'login-app'
2020-03-17 15:29:30.176 DEBUG 1 --- [nio-8081-exec-1] o.k.a.a.ClientCredentialsProviderUtils   : Loaded clientCredentialsProvider secret
2020-03-17 15:29:30.179 DEBUG 1 --- [nio-8081-exec-1] o.k.a.a.ClientCredentialsProviderUtils   : Loaded clientCredentialsProvider jwt
2020-03-17 15:29:30.182 DEBUG 1 --- [nio-8081-exec-1] o.k.a.a.ClientCredentialsProviderUtils   : Loaded clientCredentialsProvider secret-jwt
2020-03-17 15:29:30.184 DEBUG 1 --- [nio-8081-exec-1] o.k.a.a.ClientCredentialsProviderUtils   : Loaded clientCredentialsProvider secret
2020-03-17 15:29:30.185 DEBUG 1 --- [nio-8081-exec-1] o.k.a.a.ClientCredentialsProviderUtils   : Loaded clientCredentialsProvider jwt
2020-03-17 15:29:30.188 DEBUG 1 --- [nio-8081-exec-1] o.k.a.a.ClientCredentialsProviderUtils   : Loaded clientCredentialsProvider secret-jwt
2020-03-17 15:29:30.457 DEBUG 1 --- [nio-8081-exec-1] o.keycloak.adapters.KeycloakDeployment   : resolveUrls
2020-03-17 15:29:30.461 DEBUG 1 --- [nio-8081-exec-1] o.k.adapters.KeycloakDeploymentBuilder   : Use authServerUrl: https://keycloak.some.domain.com/auth, tokenUrl: https://keycloak.ci.ultrasist.net/auth/realms/SpringBootKeycloak/protocol/openid-connect/token, relativeUrls: NEVER
2020-03-17 15:29:30.479 DEBUG 1 --- [nio-8081-exec-1] .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /api/sample2.json
2020-03-17 15:29:30.481 DEBUG 1 --- [nio-8081-exec-1] o.k.a.AuthenticatedActionsHandler        : AuthenticatedActionsValve.invoke http://localhost:8081/api/sample2.json
2020-03-17 15:29:30.483 DEBUG 1 --- [nio-8081-exec-1] o.k.a.AuthenticatedActionsHandler        : Policy enforcement is disabled.
2020-03-17 15:29:30.494  INFO 1 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-03-17 15:29:30.495  INFO 1 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-03-17 15:29:30.526  INFO 1 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 29 ms
2020-03-17 15:29:30.592 DEBUG 1 --- [nio-8081-exec-1] o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8081/api/sample2.json
2020-03-17 15:29:30.694 DEBUG 1 --- [nio-8081-exec-1] o.k.a.s.management.HttpSessionManager    : Session created: E9F1974D7E734867356A0366CC0AC52A
2020-03-17 15:29:30.705 DEBUG 1 --- [nio-8081-exec-1] k.a.s.a.KeycloakAuthenticationEntryPoint : Redirecting to login URI /sso/login
2020-03-17 15:29:30.731 DEBUG 1 --- [nio-8081-exec-3] o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8081/sso/login
2020-03-17 15:29:30.735 DEBUG 1 --- [nio-8081-exec-3] .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /sso/login
2020-03-17 15:29:30.737 DEBUG 1 --- [nio-8081-exec-3] o.k.a.AuthenticatedActionsHandler        : AuthenticatedActionsValve.invoke http://localhost:8081/sso/login
2020-03-17 15:29:30.739 DEBUG 1 --- [nio-8081-exec-3] o.k.a.AuthenticatedActionsHandler        : Policy enforcement is disabled.
2020-03-17 15:29:30.757 DEBUG 1 --- [nio-8081-exec-3] o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8081/sso/login
2020-03-17 15:29:30.764 DEBUG 1 --- [nio-8081-exec-3] f.KeycloakAuthenticationProcessingFilter : Request is to process authentication
2020-03-17 15:29:30.766 DEBUG 1 --- [nio-8081-exec-3] f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
2020-03-17 15:29:30.795 DEBUG 1 --- [nio-8081-exec-3] o.k.a.s.token.SpringSecurityTokenStore   : Checking if org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticator@1273c136 is cached
2020-03-17 15:29:30.800 DEBUG 1 --- [nio-8081-exec-3] o.k.adapters.OAuthRequestAuthenticator   : there was no code
2020-03-17 15:29:30.805 DEBUG 1 --- [nio-8081-exec-3] o.k.adapters.OAuthRequestAuthenticator   : redirecting to auth server
2020-03-17 15:29:30.809 DEBUG 1 --- [nio-8081-exec-3] o.k.adapters.OAuthRequestAuthenticator   : callback uri: http://localhost:8081/sso/login
2020-03-17 15:29:30.822 DEBUG 1 --- [nio-8081-exec-3] f.KeycloakAuthenticationProcessingFilter : Auth outcome: NOT_ATTEMPTED
2020-03-17 15:29:30.824 DEBUG 1 --- [nio-8081-exec-3] o.k.adapters.OAuthRequestAuthenticator   : Sending redirect to login page: https://keycloak.some.domain.com/auth/realms/SpringBootKeycloak/protocol/openid-connect/auth?response_type=code&client_id=login-app&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fsso%2Flogin&state=412c7a6f-720f-4eea-b825-209c76d3a3db&login=true&scope=openid
2020-03-17 15:29:34.680 DEBUG 1 --- [nio-8081-exec-4] o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8081/sso/login?state=412c7a6f-720f-4eea-b825-209c76d3a3db&session_state=802e466d-7b1e-4180-8870-cdae07b2fbae&code=7d93b2cf-d72b-4e83-b219-19d48897c9b7.802e466d-7b1e-4180-8870-cdae07b2fbae.35bc9442-2e19-485a-afad-adc1e62b4c52
2020-03-17 15:29:34.687 DEBUG 1 --- [nio-8081-exec-4] .k.a.t.AbstractAuthenticatedActionsValve : AuthenticatedActionsValve.invoke /sso/login
2020-03-17 15:29:34.688 DEBUG 1 --- [nio-8081-exec-4] o.k.a.AuthenticatedActionsHandler        : AuthenticatedActionsValve.invoke http://localhost:8081/sso/login?state=412c7a6f-720f-4eea-b825-209c76d3a3db&session_state=802e466d-7b1e-4180-8870-cdae07b2fbae&code=7d93b2cf-d72b-4e83-b219-19d48897c9b7.802e466d-7b1e-4180-8870-cdae07b2fbae.35bc9442-2e19-485a-afad-adc1e62b4c52
2020-03-17 15:29:34.691 DEBUG 1 --- [nio-8081-exec-4] o.k.a.AuthenticatedActionsHandler        : Policy enforcement is disabled.
2020-03-17 15:29:34.694 DEBUG 1 --- [nio-8081-exec-4] o.k.adapters.PreAuthActionsHandler       : adminRequest http://localhost:8081/sso/login?state=412c7a6f-720f-4eea-b825-209c76d3a3db&session_state=802e466d-7b1e-4180-8870-cdae07b2fbae&code=7d93b2cf-d72b-4e83-b219-19d48897c9b7.802e466d-7b1e-4180-8870-cdae07b2fbae.35bc9442-2e19-485a-afad-adc1e62b4c52
2020-03-17 15:29:34.701 DEBUG 1 --- [nio-8081-exec-4] f.KeycloakAuthenticationProcessingFilter : Request is to process authentication
2020-03-17 15:29:34.703 DEBUG 1 --- [nio-8081-exec-4] f.KeycloakAuthenticationProcessingFilter : Attempting Keycloak authentication
2020-03-17 15:29:34.711 DEBUG 1 --- [nio-8081-exec-4] o.k.a.s.token.SpringSecurityTokenStore   : Checking if org.keycloak.adapters.springsecurity.authentication.SpringSecurityRequestAuthenticator@4c5ab508 is cached
2020-03-17 15:29:34.712 DEBUG 1 --- [nio-8081-exec-4] o.k.adapters.OAuthRequestAuthenticator   : there was a code, resolving
2020-03-17 15:29:34.712 DEBUG 1 --- [nio-8081-exec-4] o.k.adapters.OAuthRequestAuthenticator   : checking state cookie for after code
2020-03-17 15:29:34.715 DEBUG 1 --- [nio-8081-exec-4] o.k.adapters.OAuthRequestAuthenticator   : ** reseting application state cookie
2020-03-17 15:29:35.365 ERROR 1 --- [nio-8081-exec-4] o.k.adapters.OAuthRequestAuthenticator   : failed to turn code into token

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) ~[na:1.8.0_65]
 at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) ~[na:1.8.0_65]
 at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) ~[na:1.8.0_65]
 at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) ~[na:1.8.0_65]
 at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) ~[na:1.8.0_65]
 at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) ~[na:1.8.0_65]
 at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) ~[na:1.8.0_65]
 at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) ~[na:1.8.0_65]
 at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) ~[na:1.8.0_65]
 at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) ~[na:1.8.0_65]
 at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) ~[na:1.8.0_65]
 at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) ~[na:1.8.0_65]
 at org.apache.http.conn.ssl.SSLSocketFactory.createLayeredSocket(SSLSocketFactory.java:570) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.keycloak.adapters.SniSSLSocketFactory.createLayeredSocket(SniSSLSocketFactory.java:114) ~[keycloak-adapter-core-4.8.3.Final.jar!/:4.8.3.Final]
 at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:554) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.keycloak.adapters.SniSSLSocketFactory.connectSocket(SniSSLSocketFactory.java:109) ~[keycloak-adapter-core-4.8.3.Final.jar!/:4.8.3.Final]
 at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:415) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:144) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:134) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:605) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:440) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) ~[httpclient-4.5.8.jar!/:4.5.8]
 at org.keycloak.adapters.ServerRequest.invokeAccessCodeToToken(ServerRequest.java:111) ~[keycloak-adapter-core-4.8.3.Final.jar!/:4.8.3.Final]
 at org.keycloak.adapters.OAuthRequestAuthenticator.resolveCode(OAuthRequestAuthenticator.java:335) [keycloak-adapter-core-4.8.3.Final.jar!/:4.8.3.Final]
 at org.keycloak.adapters.OAuthRequestAuthenticator.authenticate(OAuthRequestAuthenticator.java:280) [keycloak-adapter-core-4.8.3.Final.jar!/:4.8.3.Final]
 at org.keycloak.adapters.RequestAuthenticator.authenticate(RequestAuthenticator.java:139) [keycloak-adapter-core-4.8.3.Final.jar!/:4.8.3.Final]
 at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.attemptAuthentication(KeycloakAuthenticationProcessingFilter.java:149) [keycloak-spring-security-adapter-4.8.3.Final.jar!/:4.8.3.Final]
 at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:86) [keycloak-spring-security-adapter-4.8.3.Final.jar!/:4.8.3.Final]
 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) [spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]
 at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.1.6.RELEASE.jar!/:5.1.6.RELEASE]
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.java:67) [spring-boot-container-bundle-4.8.3.Final.jar!/:4.8.3.Final]
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181) [spring-boot-container-bundle-4.8.3.Final.jar!/:4.8.3.Final]
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_65]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_65]
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.17.jar!/:9.0.17]
 at java.lang.Thread.run(Thread.java:745) [na:1.8.0_65]
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:387) ~[na:1.8.0_65]
 at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.8.0_65]
 at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.8.0_65]
 at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) ~[na:1.8.0_65]
 at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) ~[na:1.8.0_65]
 at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) ~[na:1.8.0_65]
 at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ~[na:1.8.0_65]
 ... 87 common frames omitted
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:146) ~[na:1.8.0_65]
 at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131) ~[na:1.8.0_65]
 at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[na:1.8.0_65]
 at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ~[na:1.8.0_65]
 ... 93 common frames omitted

2020-03-17 15:29:35.373 DEBUG 1 --- [nio-8081-exec-4] f.KeycloakAuthenticationProcessingFilter : Auth outcome: FAILED
2020-03-17 15:29:35.377 DEBUG 1 --- [nio-8081-exec-4] f.KeycloakAuthenticationProcessingFilter : Authentication request failed: org.keycloak.adapters.springsecurity.KeycloakAuthenticationException: Invalid authorization header, see WWW-Authenticate header for details

org.keycloak.adapters.springsecurity.KeycloakAuthenticationException: Invalid authorization header, see WWW-Authenticate header for details
 at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.attemptAuthentication(KeycloakAuthenticationProcessingFilter.java:157) ~[keycloak-spring-security-adapter-4.8.3.Final.jar!/:4.8.3.Final]
 at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-5.1.5.RELEASE.jar!/:5.1.5.RELEASE]

In the last error trace, I am able to see something about SSL handshake error, and other error mesage saying:

Invalid authorization header, see WWW-Authenticate header for details

but... Why this error is not present when I run the java app directly, without a docker container?

I have found some references but they are not useful for my problem:

  1. Keycloak secure app in container
  2. Docker (Spring Boot or Thorntail) and Keycloak
  3. Spring Boot Application using Keycloak, single sign on doesn't work behind an Apache Web Server

This is my Spring boot configuration class for keycloak that is part of the code that work perfectly outside the docker container but NOT inside a docker container:

@KeycloakConfiguration
class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
    KeycloakAuthenticationProvider keycloakAuthenticationProvider = keycloakAuthenticationProvider();
    keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
    auth.authenticationProvider(keycloakAuthenticationProvider);
}

@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
    return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}

@Bean
@Primary
public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
    return new KeycloakSpringBootConfigResolver();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    super.configure(http);
    http.cors().and().csrf().disable();
    http.authorizeRequests()
    .antMatchers("/api/sample*").hasRole("user")
    .antMatchers("/ui/second*").hasRole("user")
    .and()
    .logout()
    .logoutUrl("/logout")
    .logoutSuccessUrl("/")
    .permitAll();
}
}

And, this is the config for keycloak:

enter image description here

And, this is my Dockerfile were bad behavior is detected:

FROM openjdk:8
COPY app.jar /deploy/app.jar
WORKDIR /deploy
CMD java -jar app.jar

It is built by doing:

docker build . -t example

And it is executed like this:

docker run -d -p 8081:8081 example

You can see that in the last way, the security is not working properly.

Now, I have to say that, in a direct way it works great:

java -jar app.jar

So, my obviouse question (to the jboss guys or RedHat guys or any guy with the enought wisdom) is, How can I make it work Keycloak Server from within a containerized Springboot application?

Goose
  • 351
  • 4
  • 15
  • can you please provide your keycloak config in spring – Evil_skunk Mar 20 '20 at 06:21
  • done. Now it is in the post. – Goose Mar 20 '20 at 17:20
  • I'm missing the configuration for the keycloak url(in spring). The exception looks like the connection between spring and keycloak can't be established – Evil_skunk Mar 20 '20 at 20:30
  • Done. Added config info – Goose Mar 21 '20 at 03:42
  • And yes, the connection is broken if the spring app is inside a docker container. If the app is NOT inside a container, all is ok. – Goose Mar 21 '20 at 03:44
  • Has https://keycloak.myserver.net a valid SSL certificate (for https) or is it self-signed (when keycloak runs in docker)? And which java version (`java -version`) do you have when you run it locally, and which version is used inside the docker-spring-app? – Evil_skunk Mar 21 '20 at 09:26
  • Yes, I have a valid SSL certificate from Let's Encrypt. I am using java 8. However, I have tested it in localhost without SSL (and without docker) and everything works perfect. When I put the app inside a docker container (mapping the same ports 8081-->8081) then keycloak stop working and then I receive the 403 forbidden error. – Goose Mar 22 '20 at 04:24
  • To reproduce this behavior, just create ANY app using keycloak and working 100% ok at any port, like 8081. Then, put that app inside a docker container "example". Then run: "docker run -d -p 8081:8081 example" and you will see how you start receiving 403 errors when you try to authenticate... :( – Goose Mar 22 '20 at 04:30
  • I have added more info about how I created the image – Goose Mar 22 '20 at 06:02
  • I'm pretty sure the problem is, that your app (or more precisely java) is not trusting keycloaks Cert. Try to add it manually to a already existing or new generated truststore (https://stackoverflow.com/questions/373295/digital-certificate-how-to-import-cer-file-in-to-truststore-file-using). Then make sure the java process is using the trustore (https://stackoverflow.com/questions/2138574/java-path-to-truststore-set-property-doesnt-work) – Evil_skunk Mar 22 '20 at 10:24
  • But.... Why OUTSIDE docker is working well ???? (remember that it fails ONLY when I put the app INSIDE a docker container) – Goose Mar 22 '20 at 23:02
  • In other words: why should I do that when invoking my app living inside a docker container and I do not need to do that if the app is outside of a docker container? (remember: outside works 100% well) – Goose Mar 22 '20 at 23:12
  • Hey @Evil_skunk: check this out https://stackoverflow.com/questions/56523042/sslhandshakeexception-when-trying-to-access-es-instance-from-docker he had a similar problem and he found a solution. Unfortunately, It didn't work for me: -Djdk.tls.client.protocols=TLSv1.2 in my case, it should be something similar... I will continue looking for a soluition... – Goose Mar 22 '20 at 23:39
  • From a outside perspective it really looks like it is a cert issue. I'm not sure why it's not working inside the container, but it could be because of different Java versions (and their standard included trusted root certs). I would give the truststore option a try – Evil_skunk Mar 23 '20 at 05:31
  • Now, talking about SSL certificates, my keycloak server is running in an isolated node on port 8080, but I have another server (a proxy server) with nginx in which I have inyected the Let'sEncrypt SSL certificates and have re published the service on 443 port, in that proxy server, for which I have also assigned the domain name of the keycloak server. Obviously, it work well, when the app is in my isolated server without docker. But the same infrastructure with docker is not. I will change all this just to try the truststore, but I believe it wont work... lets see... – Goose Mar 23 '20 at 18:42
  • :-/ unfortuntely I haven't any other idea. But it should go quite easy and fast to create a truststore, import the cert and run your app with it - just for testing :-) – Evil_skunk Mar 23 '20 at 20:05

1 Answers1

2

Finally, after several weeks of testing, I found the answer: The bad docker image was done by using jdk 1.8.0_65-b17 and the one that worked to me was 1.8.0_232-b09:

enter image description here

So, as soon as I tested the keycloak server with this new image, everything worked as expected.

Maybe this could help someone some day with the same problem or similar.

Goose
  • 351
  • 4
  • 15