fb
WSO2 Tutorial 5 min

A 6-step guide for JWT exchange with OAuth2

jenanathan yogendran
Jenanathan Yogendran
Integration Consultant
yenlo blog 2020 05 25 jwt exchange 600x350
Scroll

A 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
Import
: Now upload the certificate to trusted IDP config.

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} 

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

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

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 secret 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 token. Endpoint 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.