HK15
HK15

Reputation: 807

Keycloak x509 client authentication configuration

I need some tips in order to understand how to perform a client authentication with x509 certificate against Keycloak.

We have a simple Spring Boot Web App (API REST) into a Kubernetes cluster. This Web App is public exsposed through an API Gateway (Ambassador) and currently protected with a browser redirection to the Keycloak login page where user can input his username and password.

However this is not what we want. What is necessary for us is a client authentication (React Native Mobile App) where:

Unfortunately I can't understand how to generate a valid and trusted x509 certificate with user data (info, roles ecc.) in order to get an access token from the IdP.

And ... how can IdP check and validate this client certificate? Is it necessary a Server certificate counterpart somewhere installed on Keycloak?

What's the correct form (ex with CURL) to pass the client certificate to keycloak? Is it neccessary to pass also the private key and why?

Upvotes: 7

Views: 40995

Answers (2)

David KELLER
David KELLER

Reputation: 636

Unfortunately I can't understand how to generate a valid and trusted x509 certificate with user data (info, roles ecc.) in order to get an access token from the IdP.

Have a look a this article to generate a certificate How to create a self-signed certificate with OpenSSL

How can IdP check and validate this client certificate?

Keycloak documentation is a good starting point, check "Adding X.509 Client Certificate Authentication to a Browser Flow" and "Adding X.509 Client Certificate Authentication to a Direct Grant Flow" if you need the whole DN for user key, you can use this RegEx on the config X509 :

  • set "A regular expression to extract user identity" : (.*)
  • add a user attribute called "usercertificate" for example and copy DN in it.

Is it necessary a Server certificate counterpart somewhere installed on Keycloak?

Not all the certificate, you can add only the DN in a user user attribute called "usercertificate".

What's the correct form (ex with CURL) to pass the client certificate to keycloak?

URL : https://localhost:9445/auth/realms//protocol/openid-connect/token

Example of code to open Keycloak TLS session :

public String openSession(
        File p12File, 
        String passphrase,
        String clientId) 
throws IOException, GeneralSecurityException {

    try (FileInputStream fis = new FileInputStream(p12File);) {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(p12File), passphrase.toCharArray());
        
        HttpClient httpClient = HttpClients
                .custom()
                .setSSLContext(new SSLContextBuilder()
                        .loadTrustMaterial(null, TrustAllStrategy.INSTANCE)
                        .loadKeyMaterial(keyStore, passphrase.toCharArray())
                        .build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
        
        HttpPost httpPost = new HttpPost(tokenEndpoint);
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");

        String data = "grant_type=password" + "&client_id="+ clientId;
        StringEntity input = new StringEntity(data);
        httpPost.setEntity(input);

        HttpResponse response = httpClient.execute(httpPost);
        return IOUtils.toString(response.getEntity().getContent(), "UTF-8");
    }
}

Is it neccessary to pass also the private key and why?

no

Upvotes: 3

cdan
cdan

Reputation: 3576

Please check the section X.509 Client Certificate User Authentication in section 6 of Keycloak Server Administration Guide, which describes:

  • how to enable and configure client certificate authentication in Wildfly and Keycloak
  • how to map certificate fields to user attributes
  • the client certificate authentication workflow with Keycloak/Wildfly (Keycloak container).

Upvotes: 4

Related Questions