Private Key JWT Client Authentication for OIDC

This section introduces you to Private Key JWT Client Authentication for OpenID Connect (OIDC) and describes how this method is used by clients when authenticating to the authorization server.


Private Key JWT Client Authentication is an authentication method that can be used by clients to authenticate to the authorization server when using the token endpoint. In this authentication mechanism, only the clients that have registered a public key, signed a JWT using that key, can authenticate.

The JWT must contain some REQUIRED claim values and may contain some OPTIONAL claim values. For more information on the required and optional claim values needed for the JWT for private_key_jwt authentication, click here .

The authentication token must be sent as the value of the client_assertion parameter. The value of the client_assertion_type parameter must be urn:ietf:params:oauth:client-assertion-type:jwt-bearer.

Deploying and configuring JWT client-handler artifacts

Follow the instructions below to deploy and configure JWT client-handler artifacts.

  1. Download the Private Key JWT Client Authenticator .

  2. Copy the downloaded org.wso2.carbon.identity.oauth2.token.handler.clientauth.jwt-x.x.x.jar to the <IS_HOME>/repository/component/dropins directory.

  3. To register the JWT grant type, configure the <IS_HOME>/repository/conf/deployment.toml file by adding a new entry as seen below.

    id = "private_key_jwt_authenticator"
    type = "org.wso2.carbon.identity.core.handler.AbstractIdentityHandler"
    name = "org.wso2.carbon.identity.oauth2.token.handler.clientauth.jwt.PrivateKeyJWTClientAuthenticator"
    order = "899"
    PreventTokenReuse= false
    RejectBeforeInMinutes= "100"
    TokenEndpointAlias= "sampleurl"

    The following table lists the optional properties that can be added to the deployment.toml file:

    Property Description
    PreventTokenReuse If this is set to "true", the JTI in the JWT should be unique per the request if the previously used JWT is not already expired. JTI (JWT ID) is a claim that provides a unique identifier for the JWT.
    RejectBeforeInMinutes The JWT should be rejected and considered as a too old token, if the issued time of the JWT exceeds the configured time.
    TokenEndpointAlias An audience that can be added from the above configuration.
  4. Do the cache configuration in <IS_HOME>/repository/conf/deployment.toml file as shown below:


    The above cache configuration is needed because when too many calls are made to the database there can be a performance impact. To reduce this impact, the cache configuration is done so that the information is read from the cache instead of the database.

  5. Restart the server.

Create a service provider

You need to register your application as a service provider in WSO2 Identity Server.

  1. Log in to the WSO2 Identity Server Management Console (https://<IS_HOST>:<PORT>/carbon) using administrator credentials (admin:admin).

  2. Navigate to Main > Identity > Service Providers > Add.

  3. Enter a Service Provider Name. Optionally, enter a Description.

  4. Click Register.

Make the following changes to the created service provider.

  1. Expand Inbound Authentication Configuration > OAuth/OpenID Connect Configuration and click Configure.

  2. Enter the Callback Url.


    The Callback Url is the exact location in the service provider's application to which an access token will be sent. This URL should be the URL of the page that the user is redirected to after successful authentication.

  3. Click Add. Note the OAuth Client Key and OAuth Client Secret that appear.


To configure more advanced configurations, see OAuth/OpenID Connect Configurations.

Configure keystore

  1. Import the public key of the private_key_jwt issuer by executing the following commands. (one after the other)

    keytool -importkeystore -srckeystore TodayApp.jks -destkeystore TodayApp.p12 -deststoretype PKCS12
    openssl pkcs12 -in TodayApp.p12 -nokeys -out pubcert.pem
  2. Rename the public key certificate file of the private_key_jwt issuer, with the ClientID (mentioned as 'alias' below) of the above auth app.

    keytool -export -alias nwU59qy9AsDqftmwLcfmkvOhvuYa -file nwU59qy9AsDqftmwLcfmkvOhvuYa -keystore TodayApp.jkskeytool -genkey -alias nwU59qy9AsDqftmwLcfmkvOhvuYa -keyalg RSA -keystore TodayApp.jks


    Note that the above 'TodayApp.jks' and 'TodayApp.p12' are sample values used to demonstrate this feature. You may need to create your own values to test the feature. Refer Create New Keystores for more information.

  3. Log in to the WSO2 Identity Server Management Console (https://<IS_HOST>:<PORT>/carbon) using administrator credentials (admin:admin).

  4. Click List under Keystores which is under Manage menu.


  5. To import the above cert in to the default key store defined in <IS_HOME>/repository/conf/deployment.toml file, click Import Cert under Actions and upload the cert. 


    In a default pack, keystore name is wso2carbon.jks.


    When you view the keystore in the same UI (using View ), there should be a certificate with clientID as below:


    Alternatively, you can import above certificate to the default key store defined in the <IS_HOME>/repository/conf/deployment.toml file. In a default pack, keystore name is wso2carbon.jks.

    keytool -import -alias nwU59qy9AsDqftmwLcfmkvOhvuYa -file nwU59qy9AsDqftmwLcfmkvOhvuYa -keystore wso2carbon.jks


    Instead of importing the service provider certificate as shown above, you can choose to use the JWKS enpoint as shown below and add the relevant JWKS URI.


  6. Use the below cURL to retrieve the access token and refresh token using a JWT.

    • For authorization code grant type:

      curl -v POST -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" -k -d "grant_type=authorization_code&code=<code>&scope=openid&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=<jwt_assertion>&redirect_uri=<callback_url>" https://<IS_HOST>:<IS_PORT>/oauth2/token

      For information on how to get the authorization-code, check Try Authorization Code Grant.

    • For client credential grant type:

      curl -v POST -H "Content-Type: application/x-www-form-urlencoded;charset=ISO-8859-1" -k -d "grant_type=client_credentials&scope=openid&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=<jwt_assertion>&redirect_uri=<callback_url>" https://<IS_HOST>:<IS_PORT>/oauth2/token