I have used the official spring-security-jwt
provided by Spring as an implementation of JWT. This toolkit is no longer maintained. And it is not particularly compatible with the latest Spring Security OAuth2 Client
and Spring Authorization Server
. So I took two days to re-implement JWT with these two new dependencies.
Nimbus Library
The JOSE library nimbus-jose-jwt
from Nimbus
is used by default in the latest Spring Security. This library is currently one of the most used JOSE class libraries and most of the transformation work has been done around this library.
The process of conversion
The process is roughly the same as the Spring Security hands-on dry run.
Load the certificate
The certificate still uses keytool to generate a 2048-length RSA key.
Here we used a more “violent” way to read KeyStore directly and then use public and private keys, this time the certificate loaded by KeyStore is transformed into JWK (Json Web Key) in JOSE specification.
JWT
JWT is defined in Spring Security as org.springframework.security.oauth2.jwt.Jwt
object, and operations on JWT can be abstracted into two aspects.
Generating JWTs
The first is JWT generation, which is not provided by Spring Security itself, but only by the incubating Spring Authorization Server
, which provides the abstract interface JwtEncoder
for JWT generation.
JWT’s
Header
andClaims
are abstracted accordingly asJoseHeader
andJwtClaimsSet
.
So I used Nimbus
to implement JwtEncoder
, which is actually a port of the Spring Authorization Server
implementation. Of course, it’s not a copy of the original, it’s just to make sure the facade is consistent, so that if the project matures, we can be seamlessly compatible.
Parsing JWT
Since there is JwtEncoder
, there must be JwtDecoder
. This is provided in the Spring Security OAuth2 Client
and is also slightly modified. In addition, this decoder is not only responsible for parsing JWT strings into JWT objects, but it also takes on the validation function, where there is a delegating validator DelegatingOAuth2TokenValidator
that we can flexibly customize to perform multiple JWT validation policies.
Token pairs
We all know that usually Tokens in JWTs come in pairs. Previously, we simply used a class to encapsulate the string form of accessToken
and refreshToken
. This time we use the OAuth2AccessTokenResponse
provided by spring ecurity oauth2 core
:
This class expresses much richer and more flexible content. The corresponding json is as follows.
|
|
Summary
The rest is largely unchanged, keeping as much of the original flavor as possible, while being compatible with the future style of Spring Security. How can you be compatible and flexible at the same time during code iteration? The key is to have a unified entry abstraction and exit abstraction. If you can do this, the quality of your code will be significantly better.
Reference
https://felord.cn/new-jwt.html