Discover our knowledge. Read our blogs!

Learn more

We build all our solutions with WSO2 and we are proud that we are Platinum Value-Added Reseller of WSO2.

Learn more

A 6-step guide for JWT exchange with OAuth2

A 6-step guide for JWT exchange with OAuth2A server-side web application uses WSO2 identity server for authentication. Authentication is carried out using OpenID connect. Once an end user is authenticated, web application needs to access some APIs published in the API Manager on behalf of the logged in user. APIs in the API Manager are protected and in order to access the APIs, web app need to get OAuth2 token for JWT token it received in login step.

WSO2 API Manager supports different OAuth2 grant types such as password, client credentials, code, JWT, et cetera. Since Web app is configured to use OpenID connect for login, it will receive the signed JWT token from the WSO2 Identity Server. Therefore, the JWT token grant type can be used to generate the OAuth token by exchanging the JWT token received in the login flow.

To run the example in this WSO2 Tutorial you must have the following prerequisites in place: WSO2 API Manager 2.6.0, WSO2 Identity Server as a Key Manager 5.7.0, Configuring Identity Server as Key Manager guide

Step 1 - Configure WSO2-IS-KM-5.7.0 as Trusted IDP in API Manager

yenlo_blog_2020-05-25_jwt-exchange-with-oauth2_figure-1

  • Login to admin console of API Manager https://<am>:9443/carbon
  • Add new Identity Provider from left panel Identity Providers -> Add
  • Give the value of <IDTokenIssuerID> in
    < WSO2-IS-KM-5.7.0 >/repository/conf/identity/identity.xml as the identity provider name

    Note: IDTokenIssuerID value configured in Identity server will be used as issuer value in JWT token generated by Identity Server. This will be used to pick up the correct identity provider config in the API Manager when it receives a JWT token for Oauth token generation Default value for IDTokenIssuerID, is OAuth2 Token endpoint URL.

    If that doesn't satisfy uncomment the following config and explicitly configure the value
    <IDTokenIssuerID>${carbon.protocol}://${carbon.host}:${carbon.
    management.port}/oauth2/token</IDTokenIssuerID>
  • Export the certificate of WSO2-IS-KM-5.7.0 and Import it to IDP configuration

    Export: Navigate to < WSO2-IS-KM-5.7.0 >/repository/resources/security and execute below command which will export the certificate to wso2.crt file

    keytool -export -alias wso2carbon -file wso2.crt -keystore wso2carbon.jks -storepass wso2carbon

    Import: Now upload the certificate to trusted IDP config 

    Choose IDP certificate type -> Upload IDP certificate

Save the configuration
yenlo_blog_2020-05-25_jwt-exchange-with-oauth2_figure-4

Step 2 - Configure Service Provider in WSO2-IS-KM for web app to login=

  • Login to admin console of Identity Server https://<is-km>:9443/carbon of WSO2-IS-KM
  • Add new Service Provider from left panel Service Providers -> Add
  • Give a name (e.g Web APP) and then configure openid connect in Inbound Authentication Configuration -> OAuth/OpenID Connect Configuration

    yenlo_blog_2020-05-25_jwt-exchange-with-oauth2_figure-5

Call Back URL: web app URL where open id connect response should be sent by IS.
Enable Audience Restriction: Token endpoint Alias provided when creating the Trusted IDP in API Manager.
Note: Audience Restriction URLs will be part of the JWT token generated by the IS

Step 3 - Publish API and subscribe

  • Create a simple API for testing in Publisher
  • Go to the Store and Create a new application
    yenlo_blog_2020-05-25_jwt-exchange-with-oauth2_figure-6
    Note : Make sure JWT grant type is selected
  • Now subscribe the API to created application

Step 4 - User login and Get ID token (JWT)

yenlo_blog_2020-05-25_jwt-exchange-with-oauth2_figure-7

Note: OpenID connect login can use different grant types. In this case assume web app is trusted and has access to user credentials and it uses password grant to login and receive OpenID connect tokens.

Request: Get the Consumer Key and Consumer Key from the Service Provider “WebAPP” created in Step 2. Username and Password should be credentials of a user who log in to the Web APP (Available in IS userstore)

curl -k -u <consumer-kery>:<consumer-secret> -d "grant_type=password&username=<username>&password=<password>&scope=openid"  https://<is-km>:9443/oauth2/token 

Response: Response will contain JWT token(id_token) which will be used to generate OAuth token in next step.

{"access_token":"a5a335e6-a025-322d-bb9a-f9497ab47ffc","refresh_token":"99e5a365-64eb-32b2-b084-4939b9e21f47","scope":"openid","id_token":"<xxxxxxx>","expires_in":2320} 

Step 5 - Generate OAuth Token for JWT token (id_token return) using JWT grant

yenlo_blog_2020-05-25_jwt-exchange-with-oauth2_figure-10

Now the user has logged into the web app and web app has the JWT token received as OpenID connect response. Now web app needs to access the API published in the API Manager on behalf of the user.

So, first web app needs to obtain a valid OAuth token by interchanging obtained JWT token using JWT grant type by calling token endpoint in APIM.

Request: Get Consumer key and Consumer secrete from the app created in API store in step 3. Use the JWT grant type to request the token. Use the id_token received in previous step for assertion.

curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' -u <consumer-key>:<consumer-secret> -k -d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<id_token>https://<apim>:8243/token 

curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' -u <consumer-key>:<consumer-secret> -k -d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<id_token>https://<apim>:8243/token 

Response: Contains OAuth access token which can be used to access the API subscribed to particular application.

{"access_token":"12c13079-9819-3676-ad64-6e46176a6607","refresh_token":"84a86921-b816-3a3a-94bf-6ea7c99cb376","scope":"default","token_type":"Bearer","expires_in":1886} 

Step 6  - Invoke API

Use the access token received in step 5 to access the published API

yenlo_blog_2020-05-25_jwt-exchange-with-oauth2_figure-13

curl -k -X GET "https://<apim>:8243/test/1/" -H "accept: application/json" -H "Authorization: Bearer 12c13079-9819-3676-ad64-6e46176a6607" 

Troubleshooting

  • Error when calling token endpoint with JWT grant type.

{"error_description":"None of the audience values matched the tokenEndpoint Alias https://xxxxxx:9443/oauth2/token","error":"invalid_grant"}. 

This error occurs because the URL in the Audience Restriction of the Service provider, which generates JWT token, doesn't match with the Token Endpoint Alias provided in Trusted IDP configuration in API Manager. To resolve, update the configurations with the correct URL accordingly.

If you have any questions on the steps described in this blog, please leave a comment below. Please reach out to us for more information about our support services.

New Call-to-action

Care to share?
   
Picture of Jenanathan Yogendran
Published May 25, 2020

Jenanathan Yogendran

Jenananthan is an Integration Consultant with more than 5 years experience in middleware integration and development. He has been part of several integration projects and his specialities are WSO2 Enterprise Service Bus, WSO2 API Manager and WSO2 Identity Server.

Responses

Stay up to date with the latest articles