[keycloak-user] Download jks-file for a confidential client

Matuszak, Eduard eduard.matuszak at worldline.com
Tue Jul 3 04:03:54 EDT 2018


Hello

I tried to get the jks-keystore file for a confidential client residing in a realm by utilizing the API

.. /certificates/jwt.credential/download

While generating and download via

../certificates/jwt.credential/generate-and-download

works fine getting a .jks-file of about 2 kb in size, the pure download afterwards gives also a .jks-file, but with only about 700 bytes in size. Both files are inspectable by keytool

keytool -list -keystore keycloak-testrealm-testclient-client.jks -storepass Pw_Kc_Str -v

, where the "generate-and-download"-file in addition gives a warning that a proprietary format is used.

It turnes out, that the creation of a token for the confidential client via the keystore-file fails with the tiny simply "dowloaded" .jks-file fails, whereas it works fine by taking the bigger "generate-and-download"ed jks-file.

My question is: Is this a bug, that ".. /certificates/jwt.credential/download" does not return the same (and proper) .jks-file than "../certificates/jwt.credential/generate-and-download" or is it possible to download the correct working .jks by other means? Inspection of Keycloak's class ClientAttributeCertificateResource did not give any suggestions to me.


Best regards , Eduard Matuszak


PS: My Keycloak version is 2.5.5

Attachment:

Here the test-bashscript I used


# -----------------------------------------------------------------------------------------------
# TEST SCRIPT
# Test if Keycloak store for client in a realm exists, create if not existing. Download in any case
# ------------------------------------------------------------------------------------------------

# TEST PARAMETERS
KEYCLOAK_HOST=<IP-address-ofKeycloak>
kcEndpoint="http://$KEYCLOAK_HOST:8080"
KEYCLOAK_ADMIN_PASSWORD=<kc_admin_password>
realmName=testrealm
clientName=testclient
kcFileNamePart=${realmName}
# TEST PARAMETERS END

echo "Getting an Access Token from Keycloak"
curl -s -D/tmp/http-result \
-d "username=admin" \
-d "password=$KEYCLOAK_ADMIN_PASSWORD" \
-d "grant_type=password" \
-d "client_id=admin-cli" \
$kcEndpoint/auth/realms/master/protocol/openid-connect/token \
| sed -n 's .*"access_token":"\([^"]*\)".* \1 p' > /tmp/kc-token
grep HTTP /tmp/http-result

#-----------------------------------------------
#Get clientId of ${clientName} if still existing
#-----------------------------------------------
echo "Get clientId of ${clientName} if still existing"
curlPath=$kcEndpoint/auth/admin/realms/${realmName}/clients
echo "using path $curlPath"
status=$(curl -s -o /dev/null \
-H "Authorization: Bearer $(</tmp/kc-token)" \
-H "Content-Type: application/json" \
-w '%{http_code}' $curlPath)
if [ $status -eq 200 ] ; then
    echo "Try to exctract clients from response..."
    clientId=$(curl $curlPath \
                -H "Authorization: Bearer $(</tmp/kc-token)" \
                -H "Content-Type: application/json" \
   | jq '.[] | select(.clientId == "'${clientName}'") | .id'  | cut -d'"' -f 2)
    echo "clientId: $clientId"
else
    echo "Error (HTTPStatus=$status): It seems that the Keycloak is not reachable via the provided path $curlPath"
    exit 1
fi


# ----------------------------------------------------------
# Keycloak > Try to download keystore file for ${clientName}
# ----------------------------------------------------------
echo "Keycloak > Try to get the keystore file for ${clientName}"
curlPath=$kcEndpoint/auth/admin/realms/${realmName}/clients/$clientId
curl -s -D/tmp/http-result \
-H "Authorization: Bearer $(</tmp/kc-token)" \
-H "Content-Type: application/json" \
-d '{"keyAlias": "'$clientName'", "realmAlias": "'$realmName'", "realmCertificate": false, "format": "JKS", "keyPassword": "Pw_Kc_Clnt", "storePassword":"Pw_Kc_Str"}' ${curlPath}/certificates/jwt.credential/download > /opt/ccp/auth/keycloak-${kcFileNamePart}-client.jks
grep HTTP /tmp/http-result
status404=$(grep HTTP /tmp/http-result | grep -c 404)
status200=$(grep HTTP /tmp/http-result | grep -c 200)
if [ $status404 -ne 0 ] ; then
                echo "No certificate created so far -> Keycloak > Generating ${clientName} client certificate and downloading keystore"
                curlPath=$kcEndpoint/auth/admin/realms/${realmName}/clients/$clientId
                curl -s -D/tmp/http-result \
                -H "Authorization: Bearer $(</tmp/kc-token)" \
                -H "Content-Type: application/json" \
                -d '{"keyAlias": "'$clientName'", "realmAlias": "'$realmName'", "realmCertificate": false, "format": "JKS", "keyPassword": "Pw_Kc_Clnt", "storePassword":"Pw_Kc_Str"}' ${curlPath}/certificates/jwt.credential/generate-and-download > /opt/ccp/auth/keycloak-${kcFileNamePart}-client.jks
                grep HTTP /tmp/http-result
else
    if [ $status200 -ne 0 ] ; then
                        echo "Keycloak > Try to download keystore file for ${clientName}"
                        curlPath=$kcEndpoint/auth/admin/realms/${realmName}/clients/$clientId
                        curl -s -D/tmp/http-result \
                        -H "Authorization: Bearer $(</tmp/kc-token)" \
                        -H "Content-Type: application/json" \
                        -d '{"keyAlias": "'$clientName'", "realmAlias": "'$realmName'", "realmCertificate": false, "format": "JKS", "keyPassword": "Pw_Kc_Clnt", "storePassword":"Pw_Kc_Str"}' ${curlPath}/certificates/jwt.credential/download > /opt/ccp/auth/keycloak-${kcFileNamePart}-client.jks
                        grep HTTP /tmp/http-result
                else
                        echo "Could not test for certificate existence for client ${clientName}"
        exit 1
    fi
fi







More information about the keycloak-user mailing list