JSON Web Token
JSON Web Token (JWT, sometimes pronounced /dʒɒt/[1]) is a JSON-based open standard (RFC 7519) for creating access tokens that assert some number of claims. For example, a server could generate a token that has the claim "logged in as admin" and provide that to a client. The client could then use that token to prove that it is logged in as admin. The tokens are signed by one party's private key (usually the server's), so that both parties (the other already being, by some suitable and trustworthy means, in possession of the corresponding public key) are able to verify that the token is legitimate. The tokens are designed to be compact,[2] URL-safe,[3] and usable especially in web browser single sign-on (SSO) context. JWT claims can be typically used to pass identity of authenticated users between an identity provider and a service provider, or any other type of claims as required by business processes.[4][5]
JWT relies on other JSON-based standards: JWS (JSON Web Signature) RFC 7515 and JWE (JSON Web Encryption) RFC 7516.[6][7][8]
Structure
Header | {
"alg" : "HS256",
"typ" : "JWT"
}
|
Identifies which algorithm is used to generate the signature
Typical cryptographic algorithms used are HMAC with SHA-256 (HS256) and RSA signature with SHA-256 (RS256). JWA (JSON Web Algorithms) RFC 7518 introduces many more for both authentication and encryption.[9] |
---|---|---|
Payload | {
"loggedInAs" : "admin",
"iat" : 1422779638
}
|
Makes claims. In this example there is a custom field claiming the user is "loggedInAs" an "admin".
As suggested in the JWT spec, the payload may include other standard fields, such as |
Signature | HMAC-SHA256(
encodeBase64Url(header) + '.' +
encodeBase64Url(payload),
secret
)
|
Securely validates the token. The signature is calculated by base64url encoding the header and payload. Base64url encoding the secret is optional. The resulting string is concatenated with a period separator, and then run through the cryptographic algorithm specified in the header, in this case HMAC-SHA256. |
The three parts are base64url encoded separately, and concatenated using periods:
const token = encodeBase64Url(header) + '.' + encodeBase64Url(payload) + '.' + encodeBase64Url(signature)
The above data and the secret of "secretkey" creates the token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI
This resulting token can be easily passed into HTML and HTTP.[3]
Use
In authentication, when the user successfully logs in using their credentials, a JSON Web Token will be returned and must be saved locally (typically in local or session storage, but cookies can also be used), instead of the traditional approach of creating a session in the server and returning a cookie.
Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization
header using the Bearer
schema. The content of the header might look like the following:
Authorization: Bearer eyJhbGci...<snip>...yu5CSpyHI
This is a stateless authentication mechanism as the user state is never saved in server memory. The server's protected routes will check for a valid JWT in the Authorization header, and if it is present, the user will be allowed to access protected resources. As JWTs are self-contained, all the necessary information is there, reducing the need to query the database multiple times.
Standard fields
The Internet drafts define the following standard fields ("claims") that can be used inside a JWT claim set:
code | name | description |
---|---|---|
iss |
Issuer | Identifies principal that issued the JWT. |
sub |
Subject | Identifies the subject of the JWT. |
aud |
Audience | Identifies the recipients that the JWT is intended for. Each principal intended to process the JWT must identify itself with a value in the audience claim. If the principal processing the claim does not identify itself with a value in the aud claim when this claim is present, then the JWT must be rejected |
exp |
Expiration time | Identifies the expiration time on or after which the JWT must not be accepted for processing. The value should be in NumericDate[10] format. |
nbf |
Not before | Identifies the time on which the JWT will start to be accepted for processing. |
iat |
Issued at | Identifies the time at which the JWT was issued. |
jti |
JWT ID | Case sensitive unique identifier of the token even among different issuers. |
The following fields can be used in authentication headers:
code | name | description |
---|---|---|
typ |
Token type | If present, it is recommended to set this to JWT . |
cty |
Content type | If nested signing or encryption is employed, it is recommended to set this to JWT , otherwise omit this field[1]. |
alg |
Message authentication code algorithm | The issuer can freely set an algorithm to verify the signature on the token. However, some supported algorithms are insecure[11]. |
All other headers introduced by JWS and JWE[7][8]. |
Implementations
JWT implementations exist for
Vulnerabilities and criticism
Because JSON web tokens are stateless, there is no way to invalidate them without storing server state, thus defeating the advantage of stateless tokens.[34]
Security consultant Tim McLean reported vulnerabilities in some JWT libraries that used the alg
field to incorrectly validate tokens. While these vulnerabilities were patched, McLean suggested deprecating the alg
field altogether to prevent similar implementation confusion.[11]
With proper design, developers can address algorithm vulnerabilities by taking precautions:[35]
- Never let the JWT header alone drive verification
- Know the algorithms
- Use an appropriate key size
References
- 1 2 3 John, Bradley; Nat, Sakimura; Michael, Jones. "JSON Web Token (JWT)". tools.ietf.org. Retrieved 2016-11-14.
- ↑ Nickel, Jochen (2016). Mastering Identity and Access Management with Microsoft Azure. p. 84. ISBN 9781785887888. Retrieved 20 July 2018.
- 1 2 "JWT.IO - JSON Web Tokens Introduction". jwt.io. Retrieved 20 July 2018.
- ↑ Sevilleja, Chris. "The Anatomy of a JSON Web Token". Retrieved 2015-05-08.
- ↑ "Atlassian Connect Documentation". developer.atlassian.com. Retrieved 2015-05-08.
- ↑ "draft-ietf-oauth-json-web-token-32 - JSON Web Token (JWT)". tools.ietf.org. Retrieved 2015-05-08.
- 1 2 "draft-ietf-jose-json-web-signature-41 - JSON Web Signature (JWS)". tools.ietf.org. Retrieved 2015-05-08.
- 1 2 "draft-ietf-jose-json-web-encryption-40 - JSON Web Encryption (JWE)". tools.ietf.org. Retrieved 2015-05-08.
- ↑ "draft-ietf-jose-json-web-algorithms-40 - JSON Web Algorithms (JWA)". tools.ietf.org. Retrieved 2015-05-08.
- ↑ John, Bradley,; Nat, Sakimura,; Michael, Jones,. "JSON Web Token (JWT)". tools.ietf.org. Retrieved 2017-12-20.
- 1 2 McLean, Tim (March 31, 2015). "Critical vulnerabilities in JSON Web Token libraries". Auth0. Retrieved 2016-03-29.
- ↑ libjwt on github.com
- ↑ cljwt on github.com
- ↑ "dgrijalva/jwt-go". GitHub. Retrieved 2018-01-08.
- ↑ jwt-dotnet on github.com
- ↑ ocaml-jwt on github.com
- ↑ Crypt::JWT on cpan.org
- ↑ JSON-WebToken on github.com
- ↑ lcobucci/jwt on github.com
- ↑ "jpadilla/pyjwt". GitHub. Retrieved 2017-03-21.
- ↑ ruby-jwt on github.com
- ↑ frank_jwt on github.com
- ↑ on github.com
- ↑ jwt-scala on github.com
- ↑ on github.com
- ↑ "liquidz/clj-jwt". GitHub. Retrieved 2018-05-07.
- ↑ "bryanjos/joken". GitHub. Retrieved 2018-05-07.
- ↑ "jwt: JSON Web Token (JWT) decoding and encoding". Hackage. Retrieved 2018-05-07.
- ↑ auth0/java-jwt on github.com
- ↑ "kjur/jsrsasign". GitHub. Retrieved 2018-05-07.
- ↑ "SkyLothar/lua-resty-jwt". GitHub. Retrieved 2018-05-07.
- ↑ "jsonwebtoken". npm. Retrieved 2018-05-07.
- ↑ "SP3269/posh-jwt". GitHub. Retrieved 2018-08-01.
- ↑ Slootweg, Sven. "Stop using JWT for sessions". joepie91 Ramblings. Retrieved 1 August 2018.
- ↑ "Common JWT security vulnerabilities and how to avoid them". Retrieved 2018-05-14.
External links
- jwt.io – specialized website about JWT with tools and documentation, maintained by Auth0
- Spring Boot JWT Auth – Integrating JWT authentication with Spring framework