refactor: Optimised codes.
Move all private or protected to the last of files.
This commit is contained in:
@@ -44,13 +44,6 @@ import java.util.UUID;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public final class AesUtil {
|
public final class AesUtil {
|
||||||
|
|
||||||
private AesUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String AES = "AES";
|
|
||||||
|
|
||||||
private static final String AES_CBC_CIPHER = "AES/CBC/PKCS5Padding";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypts the data using the AES algorithm with the given secret.
|
* Encrypts the data using the AES algorithm with the given secret.
|
||||||
*
|
*
|
||||||
@@ -133,4 +126,20 @@ public final class AesUtil {
|
|||||||
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
|
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor will protect this class from being instantiated.
|
||||||
|
*/
|
||||||
|
private AesUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The algorithm AES.
|
||||||
|
*/
|
||||||
|
private static final String AES = "AES";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The algorithm AES/CBC/PKCS5Padding.
|
||||||
|
*/
|
||||||
|
private static final String AES_CBC_CIPHER = "AES/CBC/PKCS5Padding";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,14 +56,6 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
public final class Base64Util {
|
public final class Base64Util {
|
||||||
|
|
||||||
private static Base64.Encoder encoder;
|
|
||||||
|
|
||||||
private static Base64.Decoder decoder;
|
|
||||||
|
|
||||||
private static Base64.Encoder urlEncoder;
|
|
||||||
|
|
||||||
private static Base64.Decoder urlDecoder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that there is only one Base64 Encoder.
|
* Ensure that there is only one Base64 Encoder.
|
||||||
*
|
*
|
||||||
@@ -210,4 +202,12 @@ public final class Base64Util {
|
|||||||
return decodeUrlComponents(value, StandardCharsets.UTF_8);
|
return decodeUrlComponents(value, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Base64.Encoder encoder;
|
||||||
|
|
||||||
|
private static Base64.Decoder decoder;
|
||||||
|
|
||||||
|
private static Base64.Encoder urlEncoder;
|
||||||
|
|
||||||
|
private static Base64.Decoder urlDecoder;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -77,11 +77,6 @@ import java.util.function.Supplier;
|
|||||||
*/
|
*/
|
||||||
public final class BranchUtil<T> {
|
public final class BranchUtil<T> {
|
||||||
|
|
||||||
/**
|
|
||||||
* The final result of the boolean expression.
|
|
||||||
*/
|
|
||||||
private final boolean result;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@code BranchUtil} instance.
|
* Create a {@code BranchUtil} instance.
|
||||||
*
|
*
|
||||||
@@ -239,4 +234,9 @@ public final class BranchUtil<T> {
|
|||||||
handle(ifHandler, null);
|
handle(ifHandler, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The final result of the boolean expression.
|
||||||
|
*/
|
||||||
|
private final boolean result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,12 +95,6 @@ import java.util.function.Function;
|
|||||||
@Getter
|
@Getter
|
||||||
public final class ChainedCalcUtil {
|
public final class ChainedCalcUtil {
|
||||||
|
|
||||||
/**
|
|
||||||
* -- GETTER --
|
|
||||||
* Returns the current value as a BigDecimal.
|
|
||||||
*/
|
|
||||||
private BigDecimal value;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code ChainedCalcUtil} instance with the specified initial
|
* Creates a {@code ChainedCalcUtil} instance with the specified initial
|
||||||
* value.
|
* value.
|
||||||
@@ -359,4 +353,10 @@ public final class ChainedCalcUtil {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* -- GETTER --
|
||||||
|
* Returns the current value as a BigDecimal.
|
||||||
|
*/
|
||||||
|
private BigDecimal value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,48 +69,6 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public final class HashUtil {
|
public final class HashUtil {
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor to prevent instantiation
|
|
||||||
*/
|
|
||||||
private HashUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the hash value of the specified string using the specified
|
|
||||||
* algorithm and charset.
|
|
||||||
*
|
|
||||||
* @param method the hash algorithm to use
|
|
||||||
* @param value the string to calculate the hash value for
|
|
||||||
* @param charset the charset to use for encoding the string (default is
|
|
||||||
* UTF-8 if null)
|
|
||||||
* @return the hash value as a hexadecimal string, or an empty string if
|
|
||||||
* the algorithm is not available
|
|
||||||
* @throws RuntimeException if an unknown algorithm name is provided
|
|
||||||
* (should not occur under controlled usage)
|
|
||||||
*/
|
|
||||||
private static String hash(String method, String value, Charset charset) {
|
|
||||||
try {
|
|
||||||
var messageDigest = MessageDigest.getInstance(method);
|
|
||||||
messageDigest.update(value.getBytes(charset));
|
|
||||||
var bytes = messageDigest.digest();
|
|
||||||
var builder = new StringBuilder();
|
|
||||||
|
|
||||||
for (var b : bytes) {
|
|
||||||
var str = Integer.toHexString(b & 0xff);
|
|
||||||
if (str.length() == 1) {
|
|
||||||
builder.append(0);
|
|
||||||
}
|
|
||||||
builder.append(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
} catch (NoSuchAlgorithmException ignored) {
|
|
||||||
// This should not occur under controlled usage
|
|
||||||
// Only trusted algorithms are allowed
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the MD2 hash value of the specified string using the given
|
* Calculates the MD2 hash value of the specified string using the given
|
||||||
* charset.
|
* charset.
|
||||||
@@ -286,4 +244,46 @@ public final class HashUtil {
|
|||||||
return hash("SHA-512", value, StandardCharsets.UTF_8);
|
return hash("SHA-512", value, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor will protect this class from being instantiated.
|
||||||
|
*/
|
||||||
|
private HashUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the hash value of the specified string using the specified
|
||||||
|
* algorithm and charset.
|
||||||
|
*
|
||||||
|
* @param method the hash algorithm to use
|
||||||
|
* @param value the string to calculate the hash value for
|
||||||
|
* @param charset the charset to use for encoding the string (default is
|
||||||
|
* UTF-8 if null)
|
||||||
|
* @return the hash value as a hexadecimal string, or an empty string if
|
||||||
|
* the algorithm is not available
|
||||||
|
* @throws RuntimeException if an unknown algorithm name is provided
|
||||||
|
* (should not occur under controlled usage)
|
||||||
|
*/
|
||||||
|
private static String hash(String method, String value, Charset charset) {
|
||||||
|
try {
|
||||||
|
var messageDigest = MessageDigest.getInstance(method);
|
||||||
|
messageDigest.update(value.getBytes(charset));
|
||||||
|
var bytes = messageDigest.digest();
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
for (var b : bytes) {
|
||||||
|
var str = Integer.toHexString(b & 0xff);
|
||||||
|
if (str.length() == 1) {
|
||||||
|
builder.append(0);
|
||||||
|
}
|
||||||
|
builder.append(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
} catch (NoSuchAlgorithmException ignored) {
|
||||||
|
// This should not occur under controlled usage
|
||||||
|
// Only trusted algorithms are allowed
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,12 +37,6 @@ import java.util.Map;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public final class MapUtil {
|
public final class MapUtil {
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor to prevent instantiation of MapUtil.
|
|
||||||
*/
|
|
||||||
private MapUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts an object to a map by mapping the field names to their
|
* Converts an object to a map by mapping the field names to their
|
||||||
* corresponding values.
|
* corresponding values.
|
||||||
@@ -219,4 +213,10 @@ public final class MapUtil {
|
|||||||
return String.valueOf(obj);
|
return String.valueOf(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private constructor will protect this class from being instantiated.
|
||||||
|
*/
|
||||||
|
private MapUtil() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-44
@@ -15,13 +15,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package cn.org.codecrafters.guid;
|
package cn.org.codecrafters.guid.impl;
|
||||||
|
|
||||||
|
import cn.org.codecrafters.guid.GuidCreator;
|
||||||
import cn.org.codecrafters.guid.exceptions.TimingException;
|
import cn.org.codecrafters.guid.exceptions.TimingException;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZoneOffset;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code SnowflakeGuidCreator} generates unique identifiers using the
|
* The {@code SnowflakeGuidCreator} generates unique identifiers using the
|
||||||
@@ -49,48 +49,6 @@ import java.time.ZoneOffset;
|
|||||||
*/
|
*/
|
||||||
public final class SnowflakeGuidCreator implements GuidCreator<Long> {
|
public final class SnowflakeGuidCreator implements GuidCreator<Long> {
|
||||||
|
|
||||||
/**
|
|
||||||
* Default custom epoch.
|
|
||||||
*
|
|
||||||
* @value 2015-01-01T00:00:00Z
|
|
||||||
*/
|
|
||||||
private static final long DEFAULT_CUSTOM_EPOCH = 1_420_070_400_000L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The start epoch timestamp to generate IDs from.
|
|
||||||
*/
|
|
||||||
private final long startEpoch;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of bits reserved for the worker ID.
|
|
||||||
*/
|
|
||||||
private final long workerIdBits = 5L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of bits reserved for the data centre ID.
|
|
||||||
*/
|
|
||||||
private final long dataCentreIdBits = 5L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The worker ID assigned to this generator.
|
|
||||||
*/
|
|
||||||
private final long workerId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The data centre ID assigned to this generator.
|
|
||||||
*/
|
|
||||||
private final long dataCentreId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current sequence number.
|
|
||||||
*/
|
|
||||||
private long sequence = 0L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The timestamp of the last generated ID.
|
|
||||||
*/
|
|
||||||
private long lastTimestamp = -1L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a SnowflakeGuidGenerator with the default start epoch and
|
* Constructs a SnowflakeGuidGenerator with the default start epoch and
|
||||||
* custom worker ID, data centre ID.
|
* custom worker ID, data centre ID.
|
||||||
@@ -204,5 +162,48 @@ public final class SnowflakeGuidCreator implements GuidCreator<Long> {
|
|||||||
private long currentTimestamp() {
|
private long currentTimestamp() {
|
||||||
return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default custom epoch.
|
||||||
|
*
|
||||||
|
* @value 2015-01-01T00:00:00Z
|
||||||
|
*/
|
||||||
|
private static final long DEFAULT_CUSTOM_EPOCH = 1_420_070_400_000L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start epoch timestamp to generate IDs from.
|
||||||
|
*/
|
||||||
|
private final long startEpoch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bits reserved for the worker ID.
|
||||||
|
*/
|
||||||
|
private final long workerIdBits = 5L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bits reserved for the data centre ID.
|
||||||
|
*/
|
||||||
|
private final long dataCentreIdBits = 5L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The worker ID assigned to this generator.
|
||||||
|
*/
|
||||||
|
private final long workerId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data centre ID assigned to this generator.
|
||||||
|
*/
|
||||||
|
private final long dataCentreId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current sequence number.
|
||||||
|
*/
|
||||||
|
private long sequence = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The timestamp of the last generated ID.
|
||||||
|
*/
|
||||||
|
private long lastTimestamp = -1L;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+2
-2
@@ -70,8 +70,6 @@ import java.util.Optional;
|
|||||||
*/
|
*/
|
||||||
public class PropertyGuard implements EnvironmentPostProcessor {
|
public class PropertyGuard implements EnvironmentPostProcessor {
|
||||||
|
|
||||||
private final String PREFIX = "pg";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the encryption environment variables.
|
* Process the encryption environment variables.
|
||||||
*
|
*
|
||||||
@@ -108,4 +106,6 @@ public class PropertyGuard implements EnvironmentPostProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String PREFIX = "pg";
|
||||||
}
|
}
|
||||||
|
|||||||
+130
-127
@@ -104,34 +104,6 @@ import java.util.*;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
||||||
|
|
||||||
/**
|
|
||||||
* GuidCreator used for generating unique identifiers for "jti" claim in
|
|
||||||
* JWT tokens.
|
|
||||||
*/
|
|
||||||
private final GuidCreator<?> jtiCreator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The algorithm used for signing and verifying JWT tokens.
|
|
||||||
*/
|
|
||||||
private final Algorithm algorithm;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The issuer claim value to be included in JWT tokens.
|
|
||||||
*/
|
|
||||||
private final String issuer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The JSON Web Token resolver.
|
|
||||||
*/
|
|
||||||
private final JWTVerifier verifier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jackson JSON handler.
|
|
||||||
*/
|
|
||||||
private final ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
private final AuthzeroTokenResolverConfig config = AuthzeroTokenResolverConfig.getInstance();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of {@code AuthzeroTokenResolver} with the
|
* Creates a new instance of {@code AuthzeroTokenResolver} with the
|
||||||
* provided configurations.
|
* provided configurations.
|
||||||
@@ -150,7 +122,7 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
|||||||
throw new IllegalArgumentException("A secret is required to build a JSON Web Token.");
|
throw new IllegalArgumentException("A secret is required to build a JSON Web Token.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secret.length() <= 32) {
|
if (secret.length() < 32) {
|
||||||
log.warn("The provided secret which owns {} characters is too weak. Please consider replacing it with a stronger one.", secret.length());
|
log.warn("The provided secret which owns {} characters is too weak. Please consider replacing it with a stronger one.", secret.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,104 +196,6 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
|||||||
log.info("The secret has been set to {}.", secret);
|
log.info("The secret has been set to {}.", secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the basic information of the JSON Web Token (JWT) using the
|
|
||||||
* provided parameters and adds it to the JWTCreator.Builder.
|
|
||||||
*
|
|
||||||
* @param subject the subject claim value to be included in the JWT
|
|
||||||
* @param audience an array of audience claim values to be included in
|
|
||||||
* the JWT
|
|
||||||
* @param expireAfter the duration after which the JWT will expire
|
|
||||||
* @param builder the JWTCreator.Builder instance to which the basic
|
|
||||||
* information will be added
|
|
||||||
*/
|
|
||||||
private void buildBasicInfo(JWTCreator.Builder builder, Duration expireAfter, String subject, String... audience) {
|
|
||||||
var now = LocalDateTime.now();
|
|
||||||
|
|
||||||
// bind issuer (iss)
|
|
||||||
builder.withIssuer(issuer);
|
|
||||||
// bind issued at (iat)
|
|
||||||
builder.withIssuedAt(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
|
|
||||||
// bind not before (nbf)
|
|
||||||
builder.withNotBefore(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
|
|
||||||
// bind audience (aud)
|
|
||||||
builder.withAudience(audience);
|
|
||||||
// bind subject (sub)
|
|
||||||
builder.withSubject(subject);
|
|
||||||
// bind expire at (exp)
|
|
||||||
builder.withExpiresAt(Date.from(now.plus(expireAfter).atZone(ZoneId.systemDefault()).toInstant()));
|
|
||||||
// bind JWT Id (jti)
|
|
||||||
builder.withJWTId(jtiCreator.nextId().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a claim to a builder.
|
|
||||||
*
|
|
||||||
* @param builder the builder to build this JSON Web Token
|
|
||||||
* @param name the property name
|
|
||||||
* @param value the property value
|
|
||||||
*/
|
|
||||||
private void addClaim(JWTCreator.Builder builder, String name, Object value) {
|
|
||||||
if (Objects.nonNull(value)) {
|
|
||||||
if (value instanceof Boolean v) {
|
|
||||||
builder.withClaim(name, v);
|
|
||||||
} else if (value instanceof Double v) {
|
|
||||||
builder.withClaim(name, v);
|
|
||||||
} else if (value instanceof Float v) {
|
|
||||||
builder.withClaim(name, v.doubleValue());
|
|
||||||
} else if (value instanceof Integer v) {
|
|
||||||
builder.withClaim(name, v);
|
|
||||||
} else if (value instanceof Long v) {
|
|
||||||
builder.withClaim(name, v);
|
|
||||||
} else if (value instanceof String v) {
|
|
||||||
builder.withClaim(name, v);
|
|
||||||
} else if (value instanceof Date v) {
|
|
||||||
builder.withClaim(name, v);
|
|
||||||
} else if (value instanceof List<?> v) {
|
|
||||||
builder.withClaim(name, v);
|
|
||||||
} else {
|
|
||||||
log.warn("""
|
|
||||||
Unable to determine the type of field {}, we will handle it as a String.""", name);
|
|
||||||
builder.withClaim(name, value.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
builder.withNullClaim(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the custom claims of the JSON Web Token (JWT) using the provided
|
|
||||||
* Map of claims and adds them to the JWTCreator.Builder.
|
|
||||||
* <p>
|
|
||||||
* This method is used to add custom claims to the JWT. It takes a Map of
|
|
||||||
* claims, where each entry represents a custom claim name (key) and its
|
|
||||||
* corresponding value (value). The custom claims will be added to the JWT
|
|
||||||
* using the JWTCreator.Builder.
|
|
||||||
*
|
|
||||||
* @param claims a Map containing the custom claims to be added to the JWT
|
|
||||||
* @param builder the JWTCreator.Builder instance to which the custom
|
|
||||||
* claims will be added
|
|
||||||
*/
|
|
||||||
private void buildMapClaims(JWTCreator.Builder builder, Map<String, Object> claims) {
|
|
||||||
if (Objects.nonNull(claims)) {
|
|
||||||
for (var e : claims.entrySet()) {
|
|
||||||
addClaim(builder, e.getKey(), e.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finish creating a token.
|
|
||||||
* <p>
|
|
||||||
* This is the final step of create a token, to sign this token.
|
|
||||||
*
|
|
||||||
* @param builder the builder to build this JWT
|
|
||||||
* @return the generated token as a {@code String}
|
|
||||||
*/
|
|
||||||
private String buildToken(JWTCreator.Builder builder) {
|
|
||||||
return builder.sign(algorithm);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new token with the specified expiration duration, subject, and
|
* Creates a new token with the specified expiration duration, subject, and
|
||||||
* audience.
|
* audience.
|
||||||
@@ -552,8 +426,137 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
|
|||||||
return renew(oldToken, Duration.ofMinutes(30), payload);
|
return renew(oldToken, Duration.ofMinutes(30), payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the basic information of the JSON Web Token (JWT) using the
|
||||||
|
* provided parameters and adds it to the JWTCreator.Builder.
|
||||||
|
*
|
||||||
|
* @param subject the subject claim value to be included in the JWT
|
||||||
|
* @param audience an array of audience claim values to be included in
|
||||||
|
* the JWT
|
||||||
|
* @param expireAfter the duration after which the JWT will expire
|
||||||
|
* @param builder the JWTCreator.Builder instance to which the basic
|
||||||
|
* information will be added
|
||||||
|
*/
|
||||||
|
private void buildBasicInfo(JWTCreator.Builder builder, Duration expireAfter, String subject, String... audience) {
|
||||||
|
var now = LocalDateTime.now();
|
||||||
|
|
||||||
|
// bind issuer (iss)
|
||||||
|
builder.withIssuer(issuer);
|
||||||
|
// bind issued at (iat)
|
||||||
|
builder.withIssuedAt(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
|
// bind not before (nbf)
|
||||||
|
builder.withNotBefore(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
|
// bind audience (aud)
|
||||||
|
builder.withAudience(audience);
|
||||||
|
// bind subject (sub)
|
||||||
|
builder.withSubject(subject);
|
||||||
|
// bind expire at (exp)
|
||||||
|
builder.withExpiresAt(Date.from(now.plus(expireAfter).atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
|
// bind JWT Id (jti)
|
||||||
|
builder.withJWTId(jtiCreator.nextId().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a claim to a builder.
|
||||||
|
*
|
||||||
|
* @param builder the builder to build this JSON Web Token
|
||||||
|
* @param name the property name
|
||||||
|
* @param value the property value
|
||||||
|
*/
|
||||||
|
private void addClaim(JWTCreator.Builder builder, String name, Object value) {
|
||||||
|
if (Objects.nonNull(value)) {
|
||||||
|
if (value instanceof Boolean v) {
|
||||||
|
builder.withClaim(name, v);
|
||||||
|
} else if (value instanceof Double v) {
|
||||||
|
builder.withClaim(name, v);
|
||||||
|
} else if (value instanceof Float v) {
|
||||||
|
builder.withClaim(name, v.doubleValue());
|
||||||
|
} else if (value instanceof Integer v) {
|
||||||
|
builder.withClaim(name, v);
|
||||||
|
} else if (value instanceof Long v) {
|
||||||
|
builder.withClaim(name, v);
|
||||||
|
} else if (value instanceof String v) {
|
||||||
|
builder.withClaim(name, v);
|
||||||
|
} else if (value instanceof Date v) {
|
||||||
|
builder.withClaim(name, v);
|
||||||
|
} else if (value instanceof List<?> v) {
|
||||||
|
builder.withClaim(name, v);
|
||||||
|
} else {
|
||||||
|
log.warn("""
|
||||||
|
Unable to determine the type of field {}, we will handle it as a String.""", name);
|
||||||
|
builder.withClaim(name, value.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.withNullClaim(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the custom claims of the JSON Web Token (JWT) using the provided
|
||||||
|
* Map of claims and adds them to the JWTCreator.Builder.
|
||||||
|
* <p>
|
||||||
|
* This method is used to add custom claims to the JWT. It takes a Map of
|
||||||
|
* claims, where each entry represents a custom claim name (key) and its
|
||||||
|
* corresponding value (value). The custom claims will be added to the JWT
|
||||||
|
* using the JWTCreator.Builder.
|
||||||
|
*
|
||||||
|
* @param claims a Map containing the custom claims to be added to the JWT
|
||||||
|
* @param builder the JWTCreator.Builder instance to which the custom
|
||||||
|
* claims will be added
|
||||||
|
*/
|
||||||
|
private void buildMapClaims(JWTCreator.Builder builder, Map<String, Object> claims) {
|
||||||
|
if (Objects.nonNull(claims)) {
|
||||||
|
for (var e : claims.entrySet()) {
|
||||||
|
addClaim(builder, e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish creating a token.
|
||||||
|
* <p>
|
||||||
|
* This is the final step of create a token, to sign this token.
|
||||||
|
*
|
||||||
|
* @param builder the builder to build this JWT
|
||||||
|
* @return the generated token as a {@code String}
|
||||||
|
*/
|
||||||
|
private String buildToken(JWTCreator.Builder builder) {
|
||||||
|
return builder.sign(algorithm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default type reference for Map.
|
||||||
|
*/
|
||||||
private static class MapTypeReference extends TypeReference<Map<String, Object>> {
|
private static class MapTypeReference extends TypeReference<Map<String, Object>> {
|
||||||
MapTypeReference() {
|
MapTypeReference() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GuidCreator used for generating unique identifiers for "jti" claim in
|
||||||
|
* JWT tokens.
|
||||||
|
*/
|
||||||
|
private final GuidCreator<?> jtiCreator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The algorithm used for signing and verifying JWT tokens.
|
||||||
|
*/
|
||||||
|
private final Algorithm algorithm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The issuer claim value to be included in JWT tokens.
|
||||||
|
*/
|
||||||
|
private final String issuer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The JSON Web Token resolver.
|
||||||
|
*/
|
||||||
|
private final JWTVerifier verifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jackson JSON handler.
|
||||||
|
*/
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
private final AuthzeroTokenResolverConfig config = AuthzeroTokenResolverConfig.getInstance();
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-36
@@ -62,42 +62,6 @@ import java.util.function.Function;
|
|||||||
*/
|
*/
|
||||||
public final class AuthzeroTokenResolverConfig implements TokenResolverConfig<Function<String, Algorithm>> {
|
public final class AuthzeroTokenResolverConfig implements TokenResolverConfig<Function<String, Algorithm>> {
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new instance of {@code AuthzeroTokenResolverConfig}.
|
|
||||||
* <p>
|
|
||||||
* The constructor is set as private to enforce the singleton pattern for
|
|
||||||
* this configuration class. Instances of
|
|
||||||
* {@code AuthzeroTokenResolverConfig} should be obtained through the
|
|
||||||
* {@link #getInstance()} method.
|
|
||||||
*/
|
|
||||||
private AuthzeroTokenResolverConfig() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The singleton instance of {@code AuthzeroTokenResolverConfig}.
|
|
||||||
* <p>
|
|
||||||
* This instance is used to ensure that only one instance of
|
|
||||||
* {@code AuthzeroTokenResolverConfig} is created and shared throughout the
|
|
||||||
* application. The singleton pattern is implemented to provide centralised
|
|
||||||
* configuration and avoid redundant object creation.
|
|
||||||
*/
|
|
||||||
private static AuthzeroTokenResolverConfig instance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The supported algorithms and their corresponding algorithm functions.
|
|
||||||
* <p>
|
|
||||||
* This map stores the supported algorithms as keys and their corresponding
|
|
||||||
* algorithm functions as values. The algorithm functions represent the
|
|
||||||
* functions used by the {@code com.auth0:java-jwt} library to handle the
|
|
||||||
* specific algorithms. The mapping is used to provide proper algorithm
|
|
||||||
* resolution and processing within the {@link AuthzeroTokenResolver}.
|
|
||||||
*/
|
|
||||||
private static final Map<TokenAlgorithm, Function<String, Algorithm>> SUPPORTED_ALGORITHMS = new HashMap<>() {{
|
|
||||||
put(TokenAlgorithm.HS256, Algorithm::HMAC256);
|
|
||||||
put(TokenAlgorithm.HS384, Algorithm::HMAC384);
|
|
||||||
put(TokenAlgorithm.HS512, Algorithm::HMAC512);
|
|
||||||
}};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the instance of {@code AuthzeroTokenResolverConfig}.
|
* Gets the instance of {@code AuthzeroTokenResolverConfig}.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -140,4 +104,40 @@ public final class AuthzeroTokenResolverConfig implements TokenResolverConfig<Fu
|
|||||||
return Optional.of(SUPPORTED_ALGORITHMS).map((entry) -> entry.get(algorithm))
|
return Optional.of(SUPPORTED_ALGORITHMS).map((entry) -> entry.get(algorithm))
|
||||||
.orElseThrow(() -> new UnsupportedAlgorithmException("The specified algorithm is not supported yet."));
|
.orElseThrow(() -> new UnsupportedAlgorithmException("The specified algorithm is not supported yet."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of {@code AuthzeroTokenResolverConfig}.
|
||||||
|
* <p>
|
||||||
|
* The constructor is set as private to enforce the singleton pattern for
|
||||||
|
* this configuration class. Instances of
|
||||||
|
* {@code AuthzeroTokenResolverConfig} should be obtained through the
|
||||||
|
* {@link #getInstance()} method.
|
||||||
|
*/
|
||||||
|
private AuthzeroTokenResolverConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The singleton instance of {@code AuthzeroTokenResolverConfig}.
|
||||||
|
* <p>
|
||||||
|
* This instance is used to ensure that only one instance of
|
||||||
|
* {@code AuthzeroTokenResolverConfig} is created and shared throughout the
|
||||||
|
* application. The singleton pattern is implemented to provide centralised
|
||||||
|
* configuration and avoid redundant object creation.
|
||||||
|
*/
|
||||||
|
private static AuthzeroTokenResolverConfig instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The supported algorithms and their corresponding algorithm functions.
|
||||||
|
* <p>
|
||||||
|
* This map stores the supported algorithms as keys and their corresponding
|
||||||
|
* algorithm functions as values. The algorithm functions represent the
|
||||||
|
* functions used by the {@code com.auth0:java-jwt} library to handle the
|
||||||
|
* specific algorithms. The mapping is used to provide proper algorithm
|
||||||
|
* resolution and processing within the {@link AuthzeroTokenResolver}.
|
||||||
|
*/
|
||||||
|
private static final Map<TokenAlgorithm, Function<String, Algorithm>> SUPPORTED_ALGORITHMS = new HashMap<>() {{
|
||||||
|
put(TokenAlgorithm.HS256, Algorithm::HMAC256);
|
||||||
|
put(TokenAlgorithm.HS384, Algorithm::HMAC384);
|
||||||
|
put(TokenAlgorithm.HS512, Algorithm::HMAC512);
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user