Reputation: 1831
This is my Service for generating JWTs in my Project. This, works, a user can login, retrieve a JWT and do operations with this token until its expires.
@Singleton
public class JwtService {
public String generateUserJwt() {
return generateJsonWebToken(Set.of(Role.USER));
}
public String generateAdminJwt() {
return generateJsonWebToken(Set.of(Role.ADMIN));
}
public String generateSuperAdminJwt() {
return generateJsonWebToken(Set.of(Role.USER, Role.ADMIN));
}
private String generateJsonWebToken(Set<Role> roles) {
Set<String> groups = Set.of(roles.stream().map(Role::getValue).toArray(String[]::new));
return Jwt.issuer("https://example.com")
.subject("myproject-2022-jwt")
.upn("myproject-2022-jwt")
.claim(Claims.birthdate.name(), "1985-10-25")
.groups(groups)
.expiresAt(System.currentTimeMillis() + 3600)
.sign();
}
}
Problem
Let say a User login, 10 seconds later I ban/delete his account. His JWT is still valid and he can do requests with postman using last JWT.
How I can handle this?
Upvotes: 0
Views: 104
Reputation: 14820
You can't.
The entire purpose of a JWT is to be self sustained and independent. This is why its never recommended to expose JWTs to external clients. Even though people do this all the time.
The rfc for JWTs states the following:
JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. [...] enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.
In this context, "claim" can be something like a 'command', a one-time authorization, or basically any other scenario that you can word as:
Hello Server B, Server A told me that I could , and here's the (cryptographic) proof.
This is why you need to have short lived JWT that are only valid for minutes. Because if one gets compromised you can't block/logout that user.
OWASP mentions this in their cheat sheet series, and their solution for mitigation is to implement a block list, but remember that once you do that, the entire solution is not stateless anymore, and you need to share this block list over multiple servers.
Which basically means you can use cookie sessions, as they have more protection and fulfills the same purpose.
Using JWTs as session bearers has always been a bad idea and has been mentioned over and over:
Even back in 2016 it was not advised:
Stop using JWT for sessions part 1
Stop using JWT for sessions part 2
Redis blog:
JSON Web Tokens (JWT) are Dangerous for User Sessions
Okta blog:
Why JWTs suck as user sessions
Upvotes: 1