JWT
Usually used as Access Token for Authorisation not authentication
Components
Have 3 parts separated by .
An example of a JWT token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header part
The first part eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 is Base64 encoded, contains a few headers like the hashing algorithm and the type of it:
{"alg":"HS256","typ":"JWT"}
Body part
The second part is eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ which is also Base64 encrypted:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Mandatory fields
sub: is the user idiat: issued time stamp
We can use iat to determine the expired timestamp.
Signature part
The third part is SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c which is the HS256 (declared in the first part) — which is the hash of the first 2 parts to make sure that the values were not modified.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
<256-secret>
)
We normally use this with a custom secretKey and we can verify this hash on the serverside to see if it's authentic hash.
Java
Generate a token for example
SessionUserAuthenticationDTO authenticationDTO = new SessionUserAuthenticationDTO("admin", "admin");
String token = authenticationService.authenticate(authenticationDTO)
DecodedJWT decodedJWT = authenticationService.validate(token);
assertEquals("admin", decodedJWT.getClaim("username").asString());
The code of authenticate and validate could be
@Override
public String authenticate(SessionUserAuthenticationDTO userAuthenticationDTO) {
if (userAuthenticationDTO == null) {
return null;
}
return JWT.create()
.withSubject(UUID.randomUUID().toString())
.withIssuer("localhost")
.withClaim("username", userAuthenticationDTO.username)
.withClaim("type", "access")
.sign(this.algorithm);
}
@Override
public DecodedJWT validate(String token) {
JWTVerifier verifier = JWT.require(this.algorithm).withIssuer("localhost").build();
return verifier.verify(token);
}