X509 authentication with Keycloak and Java App behind Nginx reverse proxy

I am trying to setup X509 authentication with an NGINX reverse proxy.

3 separate hosts involved:

NGNIX reverse proxy which handles SSL termination

Keycloak 11.01

Java application with Keycloak Servlet client adaptor

I have configured nginx to include the ssl-client-cert and updated nginx to use the nginx certificate lookup provider.


While debugging requests going into the application server I can see that it is including the “ssl-client-cert” header but it looks like the Keycloak Servlet client adaptor is not sending the “ssl-client-cert” header to keycloak based on the error log below (I also confirmed that header is not being sent by adding the io.undertow.server.handlers.RequestDumpingHandler filter in undertow) :

19:02:14,542 WARN  [org.keycloak.services.x509.AbstractClientCertificateFromHttpHeadersLookup] (default task-1) HTTP header "ssl-client-cert" is empty
19:02:14,544 ERROR [org.keycloak.services] (default task-1) [X509ClientCertificateAuthenticator:authenticate] Exception: null
19:02:14,544 WARN  [org.keycloak.services] (default task-1) KC-SERVICES0013: Failed authentication: org.keycloak.authentication.AuthenticationFlowException
        at org.keycloak.keycloak-services@11.0.1//org.keycloak.authentication.AuthenticationProcessor.authenticateOnly(AuthenticationProcessor.java:981)
        at org.keycloak.keycloak-services@11.0.1//org.keycloak.authentication.AuthenticationProcessor.authenticate(AuthenticationProcessor.java:840)

Is there a way to configure the keycloak servlet adapter to forward the ssl-client-cert header to keycloak?

I was able to get it working, I had the wrong url for the keycloak server. I was using the http url for the auth.server.url in keycloak.json instead of the https url. I was thinking that when the user hit my java application that the servlet adaptor would forward the “ssl-client-cert” header value that nginx sent to the app back to keycloak over the internal http connection.

In restrospect that didnt make sense because “auth-server-url” is also used to build the redirect url so it has to be the HTTPS URL that goes through the nginx SSL proxy. When the app redirects back to keycloak with HTTPS nginx will add the “ssl-client-cert” header to the request going to keycloak and it can authenticate.