feat: TokenManager supports to read a bean from a token

This commit is contained in:
siujamo
2025-04-03 10:21:42 +08:00
parent ad5b5ba146
commit 68f42f6fba
5 changed files with 98 additions and 34 deletions
@@ -17,11 +17,6 @@
package com.onixbyte.jwt;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
*
*/
@@ -0,0 +1,7 @@
package com.onixbyte.jwt;
public interface TokenManager<T> extends TokenCreator, TokenResolver {
T extract(String token);
}
@@ -17,6 +17,7 @@
package com.onixbyte.jwt;
import com.onixbyte.jwt.constant.RegisteredClaims;
import com.onixbyte.jwt.data.RawTokenComponent;
import java.util.Map;
@@ -27,30 +28,61 @@ import java.util.Map;
public interface TokenResolver {
/**
* Verifies the HMAC signature of the provided JWT.
* <p>
* Splits the token into its components and uses the configured algorithm and secret to check
* the signature's validity. If the signature does not match, an exception is thrown by the
* underlying cryptographic utility.
*
* @param token
* @param token the JWT string to verify
* @throws IllegalArgumentException if the token is malformed or the signature verification
* fails due to an invalid algorithm, key, or
* mismatched signature
*/
void verify(String token);
/**
* Retrieves the header claims from the provided JWT.
* <p>
* Decodes the Base64-encoded header and deserialises it into a map of strings.
*
* @param token
* @return
* @param token the JWT string from which to extract the header
* @return a map containing the header claims as key-value pairs
* @throws IllegalArgumentException if the token is malformed or the header cannot be
* deserialised due to invalid JSON format
*/
Map<String, String> getHeader(String token);
/**
* Retrieves the payload claims from the provided JWT, excluding registered claims.
* <p>
* Decodes the Base64-encoded payload, deserialises it into a map, and removes any registered
* claims as defined in {@link RegisteredClaims}.
*
* @param payload
* @return
* @param token the JWT string from which to extract the payload
* @return a map containing the custom payload claims as key-value pairs
* @throws IllegalArgumentException if the token is malformed or the payload cannot be
* deserialised due to invalid JSON format
*/
Map<String, Object> getPayload(String payload);
Map<String, Object> getPayload(String token);
/**
* Splits a JWT into its raw components: header, payload, and signature.
*
* @param token
* @return
* @param token the JWT string to split
* @return a {@link RawTokenComponent} containing the header, payload, and signature as strings
* @throws IllegalArgumentException if the token does not consist of exactly three parts
* separated by dots
*/
RawTokenComponent splitToken(String token);
default RawTokenComponent splitToken(String token) {
var tokenTuple = token.split("\\.");
if (tokenTuple.length != 3) {
throw new IllegalArgumentException(
"The provided JWT is invalid: it must consist of exactly three parts separated by dots.");
}
return new RawTokenComponent(tokenTuple[0], tokenTuple[1], tokenTuple[2]);
}
}
@@ -0,0 +1,50 @@
package com.onixbyte.jwt.impl;
import com.onixbyte.devkit.utils.MapUtil;
import com.onixbyte.devkit.utils.ObjectMapAdapter;
import com.onixbyte.jwt.TokenCreator;
import com.onixbyte.jwt.TokenManager;
import com.onixbyte.jwt.TokenPayload;
import com.onixbyte.jwt.TokenResolver;
import com.onixbyte.jwt.constant.Algorithm;
import java.util.Map;
public class HmacTokenManager<T> implements TokenManager<T> {
private final TokenCreator tokenCreator;
private final TokenResolver tokenResolver;
private final ObjectMapAdapter<T> adapter;
public HmacTokenManager(Algorithm algorithm, String issuer, String secret, ObjectMapAdapter<T> adapter) {
this.tokenCreator = new HmacTokenCreator(algorithm, issuer, secret);
this.tokenResolver = new HmacTokenResolver(algorithm, secret);
this.adapter = adapter;
}
@Override
public T extract(String token) {
var payloadMap = getPayload(token);
return MapUtil.mapToObject(payloadMap, adapter);
}
@Override
public String sign(TokenPayload payload) {
return tokenCreator.sign(payload);
}
@Override
public void verify(String token) {
tokenResolver.verify(token);
}
@Override
public Map<String, String> getHeader(String token) {
return tokenResolver.getHeader(token);
}
@Override
public Map<String, Object> getPayload(String token) {
return tokenResolver.getPayload(token);
}
}
@@ -73,26 +73,6 @@ public class HmacTokenResolver implements TokenResolver {
this.objectMapper = ObjectMapperHolder.getInstance().getObjectMapper();
}
/**
* Splits a JWT into its raw components: header, payload, and signature.
*
* @param token the JWT string to split
* @return a {@link RawTokenComponent} containing the header, payload, and signature as strings
* @throws IllegalArgumentException if the token does not consist of exactly three parts
* separated by dots
*/
@Override
public RawTokenComponent splitToken(String token) {
var tokenTuple = token.split("\\.");
if (tokenTuple.length != 3) {
throw new IllegalArgumentException(
"The provided JWT is invalid: it must consist of exactly three parts separated by dots.");
}
return new RawTokenComponent(tokenTuple[0], tokenTuple[1], tokenTuple[2]);
}
/**
* Verifies the HMAC signature of the provided JWT.
* <p>