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; 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; package com.onixbyte.jwt;
import com.onixbyte.jwt.constant.RegisteredClaims;
import com.onixbyte.jwt.data.RawTokenComponent; import com.onixbyte.jwt.data.RawTokenComponent;
import java.util.Map; import java.util.Map;
@@ -27,30 +28,61 @@ import java.util.Map;
public interface TokenResolver { 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); 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 * @param token the JWT string from which to extract the header
* @return * @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); 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 * @param token the JWT string from which to extract the payload
* @return * @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 * @param token the JWT string to split
* @return * @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(); 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. * Verifies the HMAC signature of the provided JWT.
* <p> * <p>