The JSON Web Token (JWT) is simply a an JSON string containing claim values. The JWT Bearer grant handler will evaluate evaluates and validate validates the claims in the JWT token, and issue issues an access token at the Authorization Server end.
WSO2 API Manager, as an OAuth 2.0 Authorization Server with its Key Manager features, can accept JWT Assertions from OAuth 2.0 clients as a means of resource owner authentication and authorization. Additionally, it can exchange the JWT token with OAuth 2.0 access tokens in order to access protected resources on behalf of the resource owner.toc
The
...
following diagram illustrates the flow when using a JWT grant type.
A client can exchange a JWT token to an a OAuth 2.0 access token using this grant type. Once an application is created on After you create an application in the API Store, you need to generate the keys for the application must be generated. When the keys are generated, there will be a Service Provider is created for the respective application on the WSO2 API Manager . The service provider entity is used by the WSO2 APIM server to obtain information of the application created on the API Store. There needs to be an Identity Provider configuration corresponding to the IDP created on the WSO2 APIM Server as well. This IDP is who creates and signs the JWT assertion. This is required (WSO2 API-M). WSO2 API Manager uses the Service Provider (SP) entity to obtain information with regard to the application, which is in the API Store. You need to create a Identity Provider (IdP), which corresponds to the Service Provider, on the WSO2 API-M Server. The IdP is responsible for creating and signing the JWT assertion, so that the server can identify the issuer of the JWT and obtain the public certificate of the IDP, in IdP in order to validate the JWT.
When a request is made to the token endpoint with the JWT grant type, the JWT assertion, the client key, and client secret, the WSO2 APIM API-M Server will read the grant type and trigger the JWT Bearer Grant Handler. This Then this handler will check checks for the issuer of the JWT token and retrieve retrieves the IDP IdP configuration. It will then obtain obtains the public certificate of the IDP IdP, which is stored in the IDP IdP configuration, and validate validates the JWT. Once the JWT is validated, it will create an OAuth2.0 access token for the application holding the provided client key and client secret.
The following sub-sections explain
...
Table of Contents | ||
---|---|---|
|
Configuring the prerequisites to use the JWT Bearer grant
Follow the instructions below to configure the prerequisites, namely the Identity Provider and the Service Provider, required in order to use the JWT Bearer grant with WSO2 API Manager.
- Sign in to the WSO2 API Store (https://localhost:9443/store).
- Create a new application if an application is not available already.
Generate the production and/or sandbox keys for the application.Anchor step3 step3 - Sign in to the WSO2 API Manager . Enter your username and password to log on to the Management Management Console (https://localhost:9443/carbon).
- Navigate to the Identity Providers section under the Main tab of the management console and click Add.
- Provide the following values to configure the IDPIdP:
- Identity Provider Name: Enter the JWT issuer name as the identity provider name. This is used to generate the JWT assertion.
Identity Provider Public Certificate: The certificate used to sign the JWT assertion.
Info title Identity provider Public Certificate The Identity Provider Public Certificate is the public certificate belonging to the identity provider. Uploading this is necessary You need to update this certificate in order to authenticate the response from the identity provider. This can be any certificate. If the identity provider is another API Manager or Identity Server, this can be a
wso2.
crt
file.To Follow the steps below to create the identity provider certificate from the
wso2carbon.jks
file, follow the steps below.1. Open :Open your Command Line interface, go to the
<APIM_HOME>/repository/resources/security
directory
, and run the following command to generate the
wso2.crt
file.Code Block keytool -export -alias wso2carbon -file wso2.crt -keystore wso2carbon.jks -storepass wso2carbon
You can find the generated
wso2.crt
file in the
<APIM_HOME>/repository/resources/security
directory.
Click Choose File
, navigate to
the location of the
wso2.crt
file, select the file and upload it.
For more information on how public keys work and how to sign these keys
using a certification authority, see Using Asymmetric Encryption in the WSO2 Administration Guide.
- Alias: Give the name of the alias if the If the Identity Provider identifies this token endpoint by an alias (e.g.,
https://localhost:9443/oauth2/token)
, enter the name of the alias.
For more information, see Adding a new identity providerand Configuring an Identity Provider in the WSO2 Identity Server documentation.
- Navigate to the Main menu to access the Identity menu. Click List under Service Providers.
- Check if there is a Service provider Provider listed for the application, which you used to generate the keys in step 3. The Service Provider name will have the the following format.
<application owner>_<application name>_<generated key type>
Using the JWT grant
The cURL commands below can be used to retrieve the After you have configured the prerequistes required to use the JWT Bearer grant, you can use the following cURL command to retrieve a access token and refresh the token using a JWT.
Code Block | ||
---|---|---|
| ||
curl -i -X POST -u <clientid>:<clientsecret> -k -d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<JWT>' -H 'Content-Type: application/x-www-form-urlencoded' https://localhost:9443/oauth2/token |
- The
-u
flag - This flag should specify the “<Client Id>:<Client Secret>
” value. - The
assertion
- The assertion parameter value is the signed the base64 encoded JWT that is signed. The value of the assertion parameter MUST contain a single JWT. You can refer JWT Bearer Grant for For more information about assertion, see JWT Assertion.
Info | ||
---|---|---|
If you have configured the service provider and identity provider Service Provider and Identity Provider in a tenant, you have to add the tenant domain as a query parameter to the access token endpoint. If For example, if the tenant domain is
|
...
Code Block | ||
---|---|---|
| ||
curl -i -X POST -H 'Content-Type: application/x-www-form-urlencoded' -u bBhEoE2wIpU1zB8HA3GfvZz8xxAa:RKgXUC3pTRQg9xPpNwyuTPGtnSQa -k -d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjE0NTgxNjY5ODUsInN1YiI6ImFkbWluIiwibmJmIjoxNDU4MTA2OTg1LCJhdWQiOlsiaHR0cHM6XC9cL2xvY2FsaG9zdDo5NDQzXC9vYXV0aDJcL3Rva2VuIiwid3NvMi1JUyJdLCJpc3MiOiJqd3RJRFAiLCJqdGkiOiJUb2tlbjU2NzU2IiwiaWF0IjoxNDU4MTA2OTg1fQ.ZcxdoTVEsWoil80ne42QzmsfelMWyjRZJEjUK1c2vMZJjjtrZnsWExyCA5tN6iXYFAXC_7rkFuuNSgOlBi51MNLPZw3WcgGI52j6apGEW92V2tib9zRRWOeLQLAdo8ae8KzLp7kuKZ2XunfQ2WYU9TvvLDm_vp5ruuYz3ZZrJOc' https://localhost:9443/oauth2/token |
Response
You would have now received The following is the response that you receive from the token endpoint based on the sample request. The response would contain contains the access token, refresh token, expiry time, and the token type.
Code Block | ||
---|---|---|
| ||
{"token_type":"Bearer","expires_in":3600,"refresh_token":"b1b4b78e2b0ef4956acb90f2e38a8833","access_token":"615ebcc943be052cf6dc27c6ec578816"} |
...
JWT Assertion
JWT contains three parts that are separated by dots ".": , namely the header, payload, and a signature. The header identifies the algorithm used to generate the signature.
...
iss
(issuer) - The JWT must contain aniss
(issuer) claim that contains a unique identifier that identifies the identity provider Identity Provider that issued the JWT.sub
(subject) - The JWT must contain asub
(subject) claim that identifies the entity that the identity provider Identity Provider or the entity that issued the JWT vouches for.aud
(audience) - The JWT must contain anaud
(audience) claim which containing a value that identifies the authorization server as an intended audience. This value should be registered as You should register this value as a token endpoint alias in the Identity Provider.exp
(expiration time) - The JWT must contain anexp
(expiration) claim that limits the time window during which you can use the JWT can be used.nbf
(not before) - The JWT may contain anbf
(not before time) claim that forces determines a specific time after which the JWT to can be used only after a specified time.iat
(issued JSON issued at) - The JWT may contain aniat
(issued at) claim that identifies the time at which the JWT was is issued.jti
(json JSON web token ID) - The JWT may contain contain anjti
(JWT ID) claim that provides a unique identifier for the token.- Other custom claims - JWT may contain claims other than the above mentioned ones. This is the extension point of the JWT specification.
...
Code Block | ||||
---|---|---|---|---|
| ||||
{ "sub":"admin", "aud":[ "https://localhost:9443/oauth2/token" ], "nbf":1507546100, "iss":"jwtIDP", "exp":1507606100, "iat":1507546100, "jti":"Token56756" } |
...
Generating a JWT assertion
- Generate the signature.
- Encode the header and the payload separately using a base64 URL.
Concatenate the encoded header and payload with a period and sign it to generate the signature.
Code Block Signature = sign(encodeBase64(header) + '.' + encodeBase64(payload))
...
- Encode the signature using a base64 URL
...
- .
Generate the JWT assertion by concatenating the values of the base64 URL encoded header, payload, and signature using a dot "." as the separator.
Code Block assertion = encodeBase64(header) + '.' + encodeBase64(payload) + '.' + encodeBase64(signature)
The result is as follows:
Code Block title Sample JWT assertion eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImF1ZCI6WyJodHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRoMlwvdG9rZW4iXSwibmJmIjoxNTA3NTQ2MTAwLCJpc3MiOiJqd3RJRFAiLCJleHAiOjE1MDc2MDYxMDAsImlhdCI6MTUwNzU0NjEwMCwianRpIjoiVG9rZW41Njc1NiJ9.iGMhjibB0W2QFQlM27gnHp6z47Eybv8cAHk2o2i-xqo2S4uJ_1VppFI4CCJXTj4qzV9vmkJ5HKNAayiTa6wOMXGL4XnwYwpOAoKXvboznlEDNRpw3htW34nLvyUu6PjHbdvAPVjh8kPRwf7esRr2p-luecGvC21mjWdhyGzM4hE