JWT
- It is
RFC 7519 - JWT (JSON Web Token) are mostly used for Authorization
- Once you are authenticated, you can send subsequent requests using Bearer schema
- JWT is encoded not encrypted. Do not put sensitive info in a JWT
- Request header:
Authorization: Bearer <JWT>
JWT = `${HEADER}.${PAYLOAD}.${SIGNATURE}`HEADER
HEADER = Base64Encoded(headerJSON)x5tis commonly used when the certificate is pre-distributed to the clientskidis commonly used when JWKS is used. Example headerJSON:
headerJSON = {
"alg": "HS256" // HMAC SHA256
"typ": "JWT",
"kid": "Mr5-AUibfBii7Nd1jBebaxboXW0"
}PAYLOAD
PAYLOAD = Base64Encoded(payloadJSON)payloadJSON contain claims
Claims types:
- Registered claims: some examples are:
iss(issuer) : where it came from… Should match authorization server eg. https://login.microsoftonline.com/35a74806-0320-4ebe-8a80-25927910263d/v2.0aud(audience) : who the token is destined for… eg. 6ad21424-b4b2-462e-80df-252ec22dd6a9, resource server uricid(client id) : should match the client id for our application that originally requested the tokeniat(issued at) :exp(expiration time) :sub(subject): user identifier
- Public claims: defined in IANA JSON Web Token Registry
- Private claims:
Example payloadJSON
payloadJSON = {
"exp": 1627988796,
"email": "Kartikey.Kumar1@blueyonder.com",
"tid": "2ac36cee-0617-4ac0-bebf-e1ce5dfab86c",
"given_name": "Kartikey",
"family_name": "Kumar",
"name": "Kartikey Kumar"
}SIGNATURE
The following are the common signing algorithms in JWT:
- RS256 (RSA Signature with SHA-256) - asymmetric algo
- HS256 (HMAC with SHA-256) - symmetric algo It is recommended to use RS256 because it is asymmetric:
- private key holder can sign tokens, while anyone can check if the token is valid using the public key.
- If the private key is compromised, you can implement key rotation without having to re-deploy your application or API with the new secret
For example, for HMAC SHA256 algorithm, the signature will be created in the following way:
SIGNATURE = HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret)Is the SIGNATURE base64 encoded again???
Validating Tokens
- Check
kidin header JSON, should match the earlier something? - Check
iss,aud,cidandexpclaims in payload JSON
Alternatives??
- Simple Web Tokens (SWT)
- Security Assertion Markup Language Tokens (SAML)
Benefits:
- JWT is smaller than SAML as SAML is based on xml
- JWT and SAML can use public/private key security
Some more terms
JWKs (JSON Web Key Set)
- it is
RFC 7517 - set of keys which contains the public keys used to verify any JSON Web Token (JWT) issued by the authorization server and signed using the RS256 signing algorithm
JWS (JSON Web Signature)
- it is
RFC 7515 - used to sign JWT
JWE (JSON Web Encryption) (used to encrypt JWT)
- it is
RFC 7516 - stands for JSON Web Encryption
- may be used for sending sensitive info
- useful in healthcare and banking
Key Rotation and how tokens are refreshed
Understanding JWT by standard
- https://datatracker.ietf.org/doc/html/rfc7519#section-1
- JWT defines claims representation format and can be transmitted as:
- JWTs are always represented using:
- JWS Compact Serialization.
- JWE Compact Serialization.
- https://datatracker.ietf.org/doc/html/rfc7515#section-3: JSON Web Signature (JWS) Overview
- JWS:
- JOSE Header
- JWS Payload
- JWS Signature
- JOSE Header
- JWS Protected Header ??? what it contains
- JWS Unprotected Header ??? what it contains
- Serializations supported:
- JWS Compact Serialization = JOSE Header has only JWS protected header
- Represented as string:
BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature) - JWS JSON Serialization = JOSE Header has union of JWS Protected + Unprotected Header
- Represented as JSON
{ "protected": BASE64URL(UTF8(JWS Protected Header)) "header": JWS Unprotected Header, "payload": BASE64URL(JWS Payload) "signature": BASE64URL(JWS Signature) }
- ref: https://stackoverflow.com/questions/27640930/what-is-the-difference-between-json-web-signature-jws-and-json-web-token-jwt