Issuing a JWT
Mint signed tokens with the built-in Nimbus encoder and choose sane claims and lifetimes.
Open this lesson in the learning hubKey points
- A JWT is signed, not encrypted. Anyone can base64-decode the payload, so never put secrets in claims.
- Keep them short-lived: 5-15 minutes. You cannot revoke a JWT, you can only outlive it. Pair it with a server-side refresh token.
- Sign with RSA or EC (
RS256) when other services verify your tokens. A shared HMAC secret only works inside one trust boundary. - Use
NimbusJwtEncoderfromspring-security-oauth2-jose. Do not hand-roll base64 and HMAC. - Include only what the API needs: subject, issuer, expiry, and the authorities used for authorization.
Example
@Bean
JwtEncoder jwtEncoder(RSAPublicKey publicKey, RSAPrivateKey privateKey) {
JWK jwk = new RSAKey.Builder(publicKey).privateKey(privateKey).build();
return new NimbusJwtEncoder(new ImmutableJWKSet<>(new JWKSet(jwk)));
}
public String issue(Authentication auth) {
Instant now = Instant.now();
String roles = auth.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(" "));
JwtClaimsSet claims = JwtClaimsSet.builder()
.issuer("https://javacodinghub.com")
.issuedAt(now)
.expiresAt(now.plus(15, ChronoUnit.MINUTES))
.subject(auth.getName())
.claim("roles", roles)
.build();
return jwtEncoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
}
Short expiry, no secrets in the payload, and let Nimbus do the signing.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Spring Security course, and every lesson in it is listed on the Spring Security contents page.