diff --git a/simple-jwt/src/main/java/com/onixbyte/jwt/TokenCreator.java b/simple-jwt/src/main/java/com/onixbyte/jwt/TokenCreator.java index d0e8f73..c05d38f 100644 --- a/simple-jwt/src/main/java/com/onixbyte/jwt/TokenCreator.java +++ b/simple-jwt/src/main/java/com/onixbyte/jwt/TokenCreator.java @@ -17,11 +17,6 @@ package com.onixbyte.jwt; -import com.fasterxml.jackson.core.JsonProcessingException; - -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; - /** * */ diff --git a/simple-jwt/src/main/java/com/onixbyte/jwt/TokenManager.java b/simple-jwt/src/main/java/com/onixbyte/jwt/TokenManager.java new file mode 100644 index 0000000..fcb596e --- /dev/null +++ b/simple-jwt/src/main/java/com/onixbyte/jwt/TokenManager.java @@ -0,0 +1,7 @@ +package com.onixbyte.jwt; + +public interface TokenManager extends TokenCreator, TokenResolver { + + T extract(String token); + +} diff --git a/simple-jwt/src/main/java/com/onixbyte/jwt/TokenResolver.java b/simple-jwt/src/main/java/com/onixbyte/jwt/TokenResolver.java index c8d1b81..1ff5fdb 100644 --- a/simple-jwt/src/main/java/com/onixbyte/jwt/TokenResolver.java +++ b/simple-jwt/src/main/java/com/onixbyte/jwt/TokenResolver.java @@ -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 @@ public interface TokenResolver { /** + * Verifies the HMAC signature of the provided JWT. + *

+ * 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. + *

+ * 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 getHeader(String token); /** + * Retrieves the payload claims from the provided JWT, excluding registered claims. + *

+ * 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 getPayload(String payload); + Map 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]); + } } diff --git a/simple-jwt/src/main/java/com/onixbyte/jwt/impl/HmacTokenManager.java b/simple-jwt/src/main/java/com/onixbyte/jwt/impl/HmacTokenManager.java new file mode 100644 index 0000000..fa3dd20 --- /dev/null +++ b/simple-jwt/src/main/java/com/onixbyte/jwt/impl/HmacTokenManager.java @@ -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 implements TokenManager { + + private final TokenCreator tokenCreator; + private final TokenResolver tokenResolver; + private final ObjectMapAdapter adapter; + + public HmacTokenManager(Algorithm algorithm, String issuer, String secret, ObjectMapAdapter 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 getHeader(String token) { + return tokenResolver.getHeader(token); + } + + @Override + public Map getPayload(String token) { + return tokenResolver.getPayload(token); + } +} diff --git a/simple-jwt/src/main/java/com/onixbyte/jwt/impl/HmacTokenResolver.java b/simple-jwt/src/main/java/com/onixbyte/jwt/impl/HmacTokenResolver.java index e0eabf1..b600a14 100644 --- a/simple-jwt/src/main/java/com/onixbyte/jwt/impl/HmacTokenResolver.java +++ b/simple-jwt/src/main/java/com/onixbyte/jwt/impl/HmacTokenResolver.java @@ -73,26 +73,6 @@ public HmacTokenResolver(Algorithm algorithm, String secret) { 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. *