'Keycloak X.509 authentication using proxy
I am trying to configure X.509 client authentication on the Keycloak 17.0.0 (Quarkus). I am using the quay.io/keycloak/keycloak:17.0.0 to deploy it in my Kubernetes environment.
I am running the Keycloak according the https://github.com/keycloak/keycloak/blob/main/docs/guides/src/main/server/reverseproxy.adoc:
/opt/keycloak/bin/kc.sh build --spi-x509cert-lookup-provider=nginx
/opt/keycloak/bin/kc.sh start-dev --spi-x509cert-lookup-nginx-ssl-client-cert=SSL_CLIENT_CERT
And I have the configuration of the X.509 client certificate authentication in the Browser and Direct Grant authentication flows, enabled in the authentication bindings, according the https://www.keycloak.org/docs/latest/server_admin/#_x509.
So expecting that the Keycloak will take the client certificate from SSL_CLIENT_CERT header and authenticate based on that.
However, trying to use the certificate to authenticate, I receive:
{
"error_description": "X509 client certificate is missing.",
"error": "invalid_request"
}
This is my curl:
curl http://localhost:8080/auth/realms/TEST/protocol/openid-connect/token \
-H "SSL_CLIENT_CERT: <cert_content>" \
-d "grant_type=password&username=&password=&client_id=CLIENT_ID&client_secret=CLIENT_SECRET"
There is a little documentation about how to do it behind the proxy in the Keycloak Quarkus version.
Anyone able to make it work?
Solution 1:[1]
1.) You need to use TLS, so you can't use http protocol for that - https is required. Ideal TLS config will have proper cert setup, otherwise curl will need --insecure.
2.) -H "SSL_CLIENT_CERT: <cert_content>" \ adds HTTP header, so that's is level 7 (OSI model), but TLS connection is level 4. So this is wrong.
Curl has another parameters --cert, --key for mutual (X.509) TLS. You should to have also proper data encoding, so in theory correct curl:
curl -s -X POST \
--cert /<path>/client-pem.crt \
--key /<path>/client-pem.key \
--data-urlencode "client_id=CLIENT_ID" \
--data-urlencode "client_secret=CLIENT_SECRET" \
--data-urlencode "grant_type=password" \
--data-urlencode "username=" \
--data-urlencode "password=" \
https://<keycloak-host>/auth/realms/TEST/protocol/openid-connect/token
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jan Garaj |
