How to Try it within 5 minutes (Private Key JWT Client Authentication Support in WSO2 Identity Server 5.5.0)

WSO2 Identity Server version 5.5.0 will be released soon and Private Key JWT Client Authentication will be an one of coolest feature coming out of WSO2 IS 5.5.0 release. You can download WSO2 Identity Server 5.5.0 release candidate 2 (wso2is-5.5.0-rc2.zip) from [a] . Same distribution will be available in [b] very soon.

If you have bit of experience with Oauth 2.0 and WSO2 Identity Server, probably you can remember token endpoint is invoked with ClientID:ClientSecret basic authentication. But this is an one of authentication method specified in [c] (client_secret_basic). Here we are going to talk about private_key_jwt client authentication mechanism where you don’t have to utilize ClientSecret at all. There you goooooooooo………..

Step 01: Install Private Key JWT Client Authenticator to Identity Server

  • You can download Private Key JWT Client Authenticator from [a]. Alternatively you can built it from source [b]. Place the org.wso2.carbon.identity.oauth2.token.handler.clientauth.jwt-x.x.x.jar in the <IS_HOME>/repository/component/dropins directory.

Step 02: Do the cache configuration

  • Configure caching in <IS_HOME>/repository/conf/identity/identity.xml as shown below [d].

<CacheConfig>

<CacheManager name="IdentityApplicationManagementCacheManager">

<Cache name="PrivateKeyJWT" enable="true" timeout="10" capacity="5000" isDistributed="false"/>

</CacheManager>

</CacheConfig>

Step 03: Create a service provider in Identity Server with Oauth/OIDC inbound authentication

OAuth/OIDC Inbound Authentication Configuration

Copy and paste the value of Client ID to some text editor, which will be useful to next steps.

Step 04: Import public key to WSO2 Identity Server

Clone [e] and navigate to “gen.jwt.nimbus/src/main/resources” directory. There you will find TodayApp.jks.

  1. Inorder to convert TodayApp.jks to PKCS12 format execute below command

keytool -importkeystore -srckeystore TodayApp.jks -destkeystore TodayApp.p12 -deststoretype PKCS12

You need to enter source keystore password and destination keystore password (For this sample I’m using wso2carbon as keystore password for both keystores)

After that you will see TodayApp.p12 in the same location.

2. Extract public cert from TodayApp.p12 keystore

openssl pkcs12 -in TodayApp.p12 -nokeys -out pubcert.pem

Enter keystore password (For this sample I’m using wso2carbon as keystore password)

After that you can see pubcert.pem in the same location.

3. Copy pubcert.pem to “<IS_HOME>/repository/resources/security”. Navigate to “<IS_HOME>/repository/resources/security” from terminal and import public cert to wso2carbon.jks

keytool -import -alias <CLIENT_ID> -keystore wso2carbon.jks -file pubcert.pem

Example :

keytool -import -alias DDSkXkPnZUqsfSEOetM6wsQteEYa -keystore wso2carbon.jks -file pubcert.pem

Enter keystore password (default password is wso2carbon).

Once you import public cert to wso2carbon.jks restart the server. Now you are done with configuration in WSO2 Identity Server side.

Step 05: Generate JWT

Navigate to “gen.jwt.nimbus/src/main/resources/config.properties” file. You will see below structure

Replace the value of iss and sub with CLIENT_ID. Come back to root directory “gen.jwt.nimbus” and execute below commands.

mvn clean install

java -jar target/gen.jwt.nimbus-1.0.0-jar-with-dependencies.jar

You can find generated JWT from below format

<header>.<body>.<signature>

eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJERFNrWGtQblpVcXNmU0VPZXRNNndzUXRlRVlhIiwiYXVkIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo5NDQzXC9vYXV0aDJcL3Rva2VuIiwiaXNzIjoiRERTa1hrUG5aVXFzZlNFT2V0TTZ3c1F0ZUVZYSIsImV4cCI6MTUyMTQ4OTE2Mjg3MiwiaWF0IjoxNTIxNDg1NTYyODg0LCJqdGkiOiI4ODIzIn0.iuyTNMmOXV0kgP4mqbq_ezkWCFxdJiqc0A6aG_ck9C67P5TdV1jo0nkmrt0ykEKiVVwdAAgryoxkeje1zqyeDenEzDY28c_SrSmzcR5wqJQXR0rq_czPhtwkGv06Zr9I4V9CBgufcfQsO64CQE72jP6x71XF_uZ1EGJzWdWnEXuqWOW7q1k4HAVdgkxbrT2YZK2TUIanzuIINCzd5I12K9h17l8Am68yRgm7uvAeQPap3wzqROr9WGoXarf3qvMi2DoibmcPpy6SiD9KHC6pRUflEziLX1Lq_5ONRim4kThYu_IqQjlQsXr-RjMcil9UJqBq89c0Ei63_GHCkRx9gw

{“alg”: “RS256”}.

{“sub”: “DDSkXkPnZUqsfSEOetM6wsQteEYa”,

“aud”: “https://localhost:9443/oauth2/token",

“iss”: “DDSkXkPnZUqsfSEOetM6wsQteEYa”,

“exp”: 1521489162872,

“iat”: 1521485562884,

“jti”: “8823”}

Step 06: Obtain Authorization Code

Copy and paste below command in browser

https://localhost:9443/oauth2/authorize?response_type=code&client_id=<CLIENT_ID>&redirect_uri=<REDIRECT_URL>

Once you enter username and password, authorization code will be received to user agent.

Sample Response

http://localhost:8080/playground2/oauth2client?code=4db636b6-1106-316d-93dd-23ab9b6d418

Step 07: Try Private Key JWT Client Authentication

Request

curl -v POST -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -k -d "grant_type=authorization_code&code=f2d0f7dd-df6d-34ac-9d61-851f4f0cab9f&scope=openid&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=<jwt_assertion>&redirect_uri=http://localhost:8080/playground2/oauth2client" https://localhost:9443/oauth2/token

Sample Request

curl -v POST -H “Content-Type: application/x-www-form-urlencoded;charset=UTF-8” -k -d “grant_type=authorization_code&code=46f59b5c-c926–3f77-ab67–63205e16688b&scope=openid&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJERFNrWGtQblpVcXNmU0VPZXRNNndzUXRlRVlhIiwiYXVkIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo5NDQzXC9vYXV0aDJcL3Rva2VuIiwiaXNzIjoiRERTa1hrUG5aVXFzZlNFT2V0TTZ3c1F0ZUVZYSIsImV4cCI6MTUyMTQ5MDU4NjkwNywiaWF0IjoxNTIxNDg2OTg2OTE5LCJqdGkiOiI2Njk2In0.YL29x8mOPEb-ftKCXB0XGzYwS-aD53N5v6Tt45–1rIxwdqYVENhDPAAsbu65JMRzXYYFNDSEA83_EIfCNV5AsufOABKUU3kemco7ZJCoCUI7Z5BXSprROskE5U-33sMxWRdhJLH7weZTRhxWy7pmp3XsBh9cvgfZEaYoISiUOEkV5BqqtAzRfDupPzLlK1z74USbYZvKyQBiXAAnBJf6nr5GT-wQbmUPhhS4fLguBVFpHQNELzAgmchhOMZ5CXQBiWNLhx_Wz9X6BaiXZY5GMS4wVk82fZoAT_MzDTvcwA3_wU-RX4SDvkxDByNUDmGIVkIehM90zakUkO8B7pcLDQ&redirect_uri=http://localhost:8080/playground2/oauth2client" https://localhost:9443/oauth2/token

Sample Response

{“access_token”:”61aced47–5bdb-35c7–9523-a7f6ba1f56ba”,”refresh_token”:”49053a35-b97e-3095–918c-b9d2be8a8c26",”token_type”:”Bearer”,”expires_in”:3600}

Reference:

[a] https://github.com/wso2/product-is/releases

[b] https://wso2.com/identity-and-access-management

[c] http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication

[d] https://docs.wso2.com/display/IS550/Private+Key+JWT+Client+Authentication+for+OIDC

[e] https://github.com/GayanM/gen.jwt.nimbus

I have been playing around WSO2 Identity Server over 5 years and helping to many production customers including active product development.