JSON Web Token (JWT) represents claims to be transferred between two parties. The claims in a JWT are encoded as a JavaScript Object Notation (JSON) object that is used as the payload of a JSON Web Signature (JWS) structure or as the plain text of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed. A JWToken is self-contained, so when we create one, it will have all the necessary pieces needed inside it.
To authenticate end users, the API manager passes attributes of the API invoker to the back-end API implementation. JWT is used to represent claims that are transferred between the end user and the backend. A claim is an attribute of the user that is mapped to the underlying user store. A set of claims are called a dialect (e.g. http://wso2.org/claims). The general format of a JWT is {token infor}.{claims list}.{signature}. The API implementation uses information, such as logging, content filtering, and authentication/authorization that is stored in this token. The token is Base64-encoded and sent to the API implementation in a HTTP header variable. The JWT header will contain three main components.
What are those pieces? The JWT token string can be divided into three parts.
A header
A payload
A signature
We will discuss about these parts later and understand them.
First let's consider very simple use case to understand the usage of API Manager JWT use case.
Let's say we have shopping cart web application. And user is invoking some web services associated with that application through API Manager. In such cases we may need to pass user details to backend service. So as discussed above we may use JWT to pass that information to backend.
Lets think we have 2 users named Bob and frank.
- Bob is 25 years old and he is enjoying watching cricket. He based on colombo, sri lanka.
- Frank is 52 years old and he enjoys watching football.He is living in frankfurt germany
They both realized coming weekend is free for them and then decided to go out to watch game.
Both Bob and Frank installed find
They both will call find ticket for games API from their mobile devices. Each time they invoke APIs we cannot ask them to send their details. They will only send access token which is mandatory for their security.
When request come to API Manager it will first validate token. Then if user is authenticated to call service we will follow up with next steps.
From access token we can get username of the user.Then we can get user attributes and create JSON payload with it.
Then API Management server will send user details as JSON payload in transport header.
So when request reach backend server they can get user details from JWT message. Then back end server will generate customized response for each user.
Bob will get response with cricket events happens around colombo area while Frank is getting response with football events happen in germany.
This is one of the most common use case of JWT.
.
In most production deployments, service calls go through the API manager or a proxy service. If we enable JWT generation in WSO2 API Manager, then each API request will carry a JWT to the back-end service. When the request goes through the API manager, we can append the JWT as a transport header to the outgoing message. So, the back-end service can fetch JWT and retrieve required information about the user, application, or token. There are two kinds of access tokens we use to invoke APIs in WSO2 API Manager.
Application access token: Generate as application owner and there is no associated user for this token (the actual user will be the application owner). In this case, all information will be fetched from the application owner, so the JWT will not have real meaning/usage when we use the application access token.
User access token: User access tokens are always bound to the user who generated token. So, when you access the API with user access token, the JWT will generate user details. On the back-end server side, we can use this to fetch user details.
Sample JWT message
{
"iss":"wso2.org/products/am","exp":1407285607264,
"http://wso2.org/claims/subscriber":"xxx@xxx.xxx",
"http://wso2.org/claims/applicationid":"2",
"http://wso2.org/claims/applicationname":"DefaultApplication",
"http://wso2.org/claims/applicationtier":"Unlimited",
"http://wso2.org/claims/apicontext":"/t/xxx.xxx/aaa/bbb",
"http://wso2.org/claims/version":"1.0.0",
"http://wso2.org/claims/tier":"Unlimited",
"http://wso2.org/claims/keytype":"PRODUCTION",
"http://wso2.org/claims/usertype":"APPLICATION",
"http://wso2.org/claims/enduser":"anonymous",
"http://wso2.org/claims/enduserTenantId":"1",
"http://wso2.org/claims/emailaddress":"sanjeewa@wso2.com",
"http://wso2.org/claims/fullname":"xxx",
"http://wso2.org/claims/givenname":"xxx",
"http://wso2.org/claims/lastname":"xxx",
"http://wso2.org/claims/role":"admin,subscriber,Internal/everyone"
}
As you can see JWT contain claims associated with User (end user TenantId, full name, given name, last name, role, email address, user type) API (API context, version, tier), Subscription (keytype, subscriber)
Application (application ID, application name, application tier)
However, in some production deployments, we might need to generate custom attributes and embedded to the JWT.