@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt;
|
||||
|
||||
import com.onixbyte.simplejwt.exceptions.WeakSecretException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* {@code SecretCreator} is a utility class that provides methods to generate
|
||||
* secure secret strings. The generated secrets can be used as cryptographic
|
||||
* keys or passwords for various security-sensitive purposes.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class SecretCreator {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(SecretCreator.class);
|
||||
|
||||
/**
|
||||
* Generates a secure secret with the specified length and character sets.
|
||||
*
|
||||
* @param length the length of the secret to be generated
|
||||
* @param isContainCapital flag indicating if the secret should contain
|
||||
* uppercase letters
|
||||
* @param isContainDigital flag indicating if the secret should contain
|
||||
* digits
|
||||
* @param isContainSpecialSign flag indicating if the secret should contain
|
||||
* special sign characters
|
||||
* @return the generated secure secret
|
||||
* @throws WeakSecretException if the requested secret length is less than
|
||||
* 32 characters
|
||||
*/
|
||||
public static String createSecret(int length,
|
||||
boolean isContainCapital,
|
||||
boolean isContainDigital,
|
||||
boolean isContainSpecialSign) {
|
||||
if (length < 32) {
|
||||
throw new WeakSecretException("""
|
||||
The requested secret, which is only %d characters long, is too weak. \
|
||||
Please replace it with a stronger secret.""".formatted(length));
|
||||
}
|
||||
|
||||
final var randomiser = new Random();
|
||||
var charset = new StringBuilder(LOWERCASE_CHARACTERS);
|
||||
|
||||
if (isContainCapital) charset.append(UPPERCASE_CHARACTERS);
|
||||
if (isContainDigital) charset.append(DIGITS);
|
||||
if (isContainSpecialSign) charset.append(SPECIAL_SIGNS);
|
||||
|
||||
var secretBuilder = new StringBuilder();
|
||||
var charsetSize = charset.length();
|
||||
for (var i = 0; i < length; ++i) {
|
||||
secretBuilder.append(charset.charAt(randomiser.nextInt(charsetSize)));
|
||||
}
|
||||
|
||||
return secretBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a secure secret with the specified length, containing
|
||||
* uppercase letters and digits.
|
||||
*
|
||||
* @param length the length of the secret to be generated
|
||||
* @param isContainCapital flag indicating if the secret should contain
|
||||
* uppercase letters
|
||||
* @param isContainDigital flag indicating if the secret should contain
|
||||
* digits
|
||||
* @return the generated secure secret
|
||||
* @throws WeakSecretException if the requested secret length is less than
|
||||
* 32 characters
|
||||
* @see #createSecret(int, boolean, boolean, boolean)
|
||||
*/
|
||||
public static String createSecret(int length,
|
||||
boolean isContainCapital,
|
||||
boolean isContainDigital) {
|
||||
return createSecret(length, isContainCapital, isContainDigital, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a secure secret with the specified length, containing
|
||||
* uppercase letters.
|
||||
*
|
||||
* @param length the length of the secret to be generated
|
||||
* @param isContainCapital flag indicating if the secret should contain
|
||||
* uppercase letters
|
||||
* @return the generated secure secret
|
||||
* @throws WeakSecretException if the requested secret length is less than
|
||||
* 32 characters
|
||||
* @see #createSecret(int, boolean, boolean, boolean)
|
||||
*/
|
||||
public static String createSecret(int length,
|
||||
boolean isContainCapital) {
|
||||
return createSecret(length, isContainCapital, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a secure secret with the specified length, containing
|
||||
* lowercase letters.
|
||||
*
|
||||
* @param length the length of the secret to be generated
|
||||
* @return the generated secure secret
|
||||
* @throws WeakSecretException if the requested secret length is less than
|
||||
* 32 characters
|
||||
* @see #createSecret(int, boolean, boolean, boolean)
|
||||
*/
|
||||
public static String createSecret(int length) {
|
||||
return createSecret(length, false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation of this utility class.
|
||||
*/
|
||||
private SecretCreator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The string containing all lowercase characters that can be used to
|
||||
* generate the secret.
|
||||
*/
|
||||
private static final String LOWERCASE_CHARACTERS = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
/**
|
||||
* The string containing all uppercase characters that can be used to
|
||||
* generate the secret.
|
||||
*/
|
||||
private static final String UPPERCASE_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
/**
|
||||
* The string containing all digit characters that can be used to generate
|
||||
* the secret.
|
||||
*/
|
||||
private static final String DIGITS = "0123456789";
|
||||
|
||||
/**
|
||||
* The string containing all special sign characters that can be used to
|
||||
* generate the secret.
|
||||
*/
|
||||
private static final String SPECIAL_SIGNS = "!@#$%^&,*()_+-=,[]{}|;:,'\",.<>/?";
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt;
|
||||
|
||||
/**
|
||||
* {@code TokenPayload} interface is used to mark a data class as suitable
|
||||
* for being used as the payload in a JSON Web Token (JWT). Any class
|
||||
* implementing this interface can be used to represent the payload data that
|
||||
* will be included in a JWT.
|
||||
* <p>
|
||||
* Implementing this interface indicates that the data class contains
|
||||
* information that needs to be securely transmitted and verified as part of a
|
||||
* JWT. The payload typically contains claims or attributes that provide
|
||||
* additional information about the JWT subject or context.
|
||||
* <p>
|
||||
* <b>Usage:</b>
|
||||
* To use a class as a JWT payload, simply implement the {@code TokenPayload}
|
||||
* interface in the data class:
|
||||
* <pre>
|
||||
* public class UserData implements TokenPayload {
|
||||
* // Class implementation with payload data...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface TokenPayload {
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@code TokenResolver} defines methods for creating, extracting, and
|
||||
* renewing tokens, particularly JSON Web Tokens (JWTs). It provides a set of
|
||||
* methods to generate tokens with various payload configurations, extract
|
||||
* payload from tokens, and renew expired tokens.
|
||||
* <p>
|
||||
* <b>Token Creation:</b>
|
||||
* The interface provides overloaded methods for creating tokens with different
|
||||
* payload configurations, including expiration time, audience, subject, and
|
||||
* custom payload data. Clients can choose the appropriate method based on
|
||||
* their specific token requirements.
|
||||
* <p>
|
||||
* <b>Token Extraction:</b>
|
||||
* The interface includes methods to extract payload information from a given
|
||||
* token. Clients can use these methods to obtain the payload data encoded in
|
||||
* the token.
|
||||
* <p>
|
||||
* <b>Token Renewal:</b>
|
||||
* The interface also offers methods for token renewal. Clients can renew an
|
||||
* expired token by providing a new expiration time, audience, subject, and
|
||||
* optional custom payload data.
|
||||
*
|
||||
* @param <ResolvedTokenType> the type of the result obtained by the
|
||||
* third-party library when parsing JWTs
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface TokenResolver<ResolvedTokenType> {
|
||||
|
||||
/**
|
||||
* Creates a new token with the specified expiration time, subject, and
|
||||
* audience.
|
||||
*
|
||||
* @param expireAfter the duration after which the token will expire
|
||||
* @param subject the subject of the token
|
||||
* @param audience the audience for which the token is intended
|
||||
* @return the generated token as a {@code String}
|
||||
*/
|
||||
String createToken(Duration expireAfter, String audience, String subject);
|
||||
|
||||
/**
|
||||
* Creates a new token with the specified expiration time, subject,
|
||||
* audience, and custom payload data.
|
||||
*
|
||||
* @param expireAfter the duration after which the token will expire
|
||||
* @param subject the subject of the token
|
||||
* @param audience the audience for which the token is intended
|
||||
* @param payload the custom payload data to be included in the token
|
||||
* @return the generated token as a {@code String}
|
||||
*/
|
||||
String createToken(Duration expireAfter, String audience, String subject, Map<String, Object> payload);
|
||||
|
||||
/**
|
||||
* Creates a new token with the specified expiration time, subject,
|
||||
* audience, and strongly-typed payload data.
|
||||
*
|
||||
* @param <T> the type of the payload data, must implement
|
||||
* {@link TokenPayload}
|
||||
* @param expireAfter the duration after which the token will expire
|
||||
* @param subject the subject of the token
|
||||
* @param audience the audience for which the token is intended
|
||||
* @param payload the strongly-typed payload data to be included in the
|
||||
* token
|
||||
* @return the generated token as a {@code String}
|
||||
*/
|
||||
<T extends TokenPayload> String createToken(Duration expireAfter, String audience, String subject, T payload);
|
||||
|
||||
/**
|
||||
* Resolves the given token into a ResolvedTokenType object.
|
||||
*
|
||||
* @param token the token to be resolved
|
||||
* @return a ResolvedTokenType object
|
||||
*/
|
||||
ResolvedTokenType resolve(String token);
|
||||
|
||||
/**
|
||||
* Extracts the payload information from the given token and maps it to the
|
||||
* specified target type.
|
||||
*
|
||||
* @param <T> the target type to which the payload data will be
|
||||
* mapped
|
||||
* @param token the token from which to extract the payload
|
||||
* @param targetType the target class representing the payload data type
|
||||
* @return an instance of the specified target type with the extracted
|
||||
* payload data
|
||||
*/
|
||||
<T extends TokenPayload> T extract(String token, Class<T> targetType);
|
||||
|
||||
/**
|
||||
* Re-generate a new token with the payload in the old one.
|
||||
*
|
||||
* @param oldToken the old token
|
||||
* @param expireAfter how long the new token can be valid for
|
||||
* @return re-generated token with the payload in the old one
|
||||
*/
|
||||
String renew(String oldToken, Duration expireAfter);
|
||||
|
||||
/**
|
||||
* Re-generate a new token with the payload in the old one.
|
||||
*
|
||||
* @param oldToken the old token
|
||||
* @return re-generated token with the payload in the old one
|
||||
* @see #renew(String, Duration)
|
||||
*/
|
||||
default String renew(String oldToken) {
|
||||
return renew(oldToken, Duration.ofMinutes(30));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renews the given expired token with the specified custom payload data.
|
||||
*
|
||||
* @param oldToken the expired token to be renewed
|
||||
* @param expireAfter specify when does the new token invalid
|
||||
* @param payload the custom payload data to be included in the renewed
|
||||
* token
|
||||
* @return the renewed token as a {@code String}
|
||||
*/
|
||||
String renew(String oldToken, Duration expireAfter, Map<String, Object> payload);
|
||||
|
||||
/**
|
||||
* Renews the given expired token with the specified custom payload data.
|
||||
*
|
||||
* @param oldToken the expired token to be renewed
|
||||
* @param payload the custom payload data to be included in the renewed
|
||||
* token
|
||||
* @return the renewed token as a {@code String}
|
||||
*/
|
||||
default String renew(String oldToken, Map<String, Object> payload) {
|
||||
return renew(oldToken, Duration.ofMinutes(30), payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renews the given expired token with the specified strongly-typed
|
||||
* payload data.
|
||||
*
|
||||
* @param <T> the type of the payload data, must implement
|
||||
* {@link TokenPayload}
|
||||
* @param oldToken the expired token to be renewed
|
||||
* @param expireAfter specify when does the new token invalid
|
||||
* @param payload the strongly-typed payload data to be included in the
|
||||
* renewed token
|
||||
* @return the renewed token as a {@code String}
|
||||
*/
|
||||
<T extends TokenPayload> String renew(String oldToken, Duration expireAfter, T payload);
|
||||
|
||||
/**
|
||||
* Renews the given expired token with the specified strongly-typed
|
||||
* payload data.
|
||||
*
|
||||
* @param <T> the type of the payload data, must implement
|
||||
* {@link TokenPayload}
|
||||
* @param oldToken the expired token to be renewed
|
||||
* @param payload the strongly-typed payload data to be included in the
|
||||
* renewed token
|
||||
* @return the renewed token as a {@code String}
|
||||
*/
|
||||
default <T extends TokenPayload> String renew(String oldToken, T payload) {
|
||||
return renew(oldToken, Duration.ofMinutes(30), payload);
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation {@code ExcludeFromPayload} is used to mark a property of a data
|
||||
* class that should be excluded from being automatically injected into the
|
||||
* JSON Web Token (JWT) payload during token generation. When a property is
|
||||
* annotated by this annotation, it will not be included in the JWT payloads.
|
||||
* <p>
|
||||
* <b>Usage:</b>
|
||||
* To exclude a property from the JWT payload, annotate the property with
|
||||
* {@code @ExcludeFromPayload}:
|
||||
*
|
||||
* <pre>{@code
|
||||
* public class UserData implements TokenPayload {
|
||||
* private String username;
|
||||
*
|
||||
* // This property will not be included in the JWT payload
|
||||
* @ExcludeFromPayload
|
||||
* private String sensitiveData;
|
||||
*
|
||||
* // Getters and setters...
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>
|
||||
* <b>Note:</b>
|
||||
* This annotation should be used on properties that are not intended to
|
||||
* be included in the JWT payload due to their sensitive nature or for other
|
||||
* reasons only. It is important to carefully choose which properties are
|
||||
* excluded from the payload to ensure the JWT remains secure and efficient.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface ExcludeFromPayload {
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.annotations;
|
||||
|
||||
import com.onixbyte.simplejwt.constants.TokenDataType;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This annotation marks the enum field declared in payload class will be handled as basic data
|
||||
* types in {@link TokenDataType}.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface TokenEnum {
|
||||
|
||||
/**
|
||||
* The name of the field of the base data corresponding to the enumeration data.
|
||||
*
|
||||
* @return the name of the property
|
||||
*/
|
||||
String propertyName();
|
||||
|
||||
/**
|
||||
* The attribute {@code dataType} specifies what base data type to treat this enum as.
|
||||
*
|
||||
* @return the data type of the token
|
||||
*/
|
||||
TokenDataType dataType();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.constants;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The {@code PredefinedKeys} class contains constants for standard JSON Web Token (JWT) claims. These constants
|
||||
* represent the names of the standard claims that can be included in a JWT payload. Developers can use these constants
|
||||
* when working with JWTs to ensure consistent naming of the claims.
|
||||
* <p>
|
||||
* The class provides the following standard JWT claim constants:
|
||||
* <ul>
|
||||
* <li>{@link #ISSUER}: Represents the "iss" (Issuer) claim.</li>
|
||||
* <li>{@link #SUBJECT}: Represents the "sub" (Subject) claim.</li>
|
||||
* <li>{@link #AUDIENCE}: Represents the "aud" (Audience) claim.</li>
|
||||
* <li>{@link #EXPIRATION_TIME}: Represents the "exp" (Expiration Time) claim.</li>
|
||||
* <li>{@link #NOT_BEFORE}: Represents the "nbf" (Not Before) claim.</li>
|
||||
* <li>{@link #ISSUED_AT}: Represents the "iat" (Issued At) claim.</li>
|
||||
* <li>{@link #JWT_ID}: Represents the "jti" (JWT ID) claim.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The class also contains a list of all the standard claim constants, accessible via the {@link
|
||||
* #KEYS} field. This list can be useful for iterating through all the standard claims or checking
|
||||
* for the presence of specific claims.
|
||||
* <p>
|
||||
* Note: This class is final and cannot be instantiated. It only serves as a utility class to hold
|
||||
* the standard JWT claim constants.
|
||||
*
|
||||
* @author zihluwang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class PredefinedKeys {
|
||||
|
||||
/**
|
||||
* Constant representing the "iss" (Issuer) claim in a JWT payload.
|
||||
*/
|
||||
public static final String ISSUER = "iss";
|
||||
|
||||
/**
|
||||
* Constant representing the "sub" (Subject) claim in a JWT payload.
|
||||
*/
|
||||
public static final String SUBJECT = "sub";
|
||||
|
||||
/**
|
||||
* Constant representing the "aud" (Audience) claim in a JWT payload.
|
||||
*/
|
||||
public static final String AUDIENCE = "aud";
|
||||
|
||||
/**
|
||||
* Constant representing the "exp" (Expiration Time) claim in a JWT payload.
|
||||
*/
|
||||
public static final String EXPIRATION_TIME = "exp";
|
||||
|
||||
/**
|
||||
* Constant representing the "nbf" (Not Before) claim in a JWT payload.
|
||||
*/
|
||||
public static final String NOT_BEFORE = "nbf";
|
||||
|
||||
/**
|
||||
* Constant representing the "iat" (Issued At) claim in a JWT payload.
|
||||
*/
|
||||
public static final String ISSUED_AT = "iat";
|
||||
|
||||
/**
|
||||
* Constant representing the "jti" (JWT ID) claim in a JWT payload.
|
||||
*/
|
||||
public static final String JWT_ID = "jti";
|
||||
|
||||
/**
|
||||
* List containing all the standard JWT claim constants.
|
||||
*/
|
||||
public static final List<String> KEYS =
|
||||
List.of(ISSUER, SUBJECT, AUDIENCE, EXPIRATION_TIME, NOT_BEFORE, ISSUED_AT, JWT_ID);
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation of this utility class.
|
||||
*/
|
||||
private PredefinedKeys() {
|
||||
}
|
||||
}
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.constants;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The {@code TokenAlgorithm} enum class defines the algorithms that can be
|
||||
* used for signing and verifying JSON Web Tokens (JWT). JWT allows various
|
||||
* cryptographic algorithms to be used for secure token generation and
|
||||
* validation. This enum provides a list of supported algorithms to ensure
|
||||
* consistent usage and avoid potential security issues.
|
||||
* <p>
|
||||
* <b>Supported Algorithms:</b>
|
||||
* <ul>
|
||||
* <li>{@link TokenAlgorithm#HS256}: HMAC SHA-256</li>
|
||||
* <li>{@link TokenAlgorithm#HS384}: HMAC SHA-384</li>
|
||||
* <li>{@link TokenAlgorithm#HS512}: HMAC SHA-512</li>
|
||||
* <li>{@link TokenAlgorithm#RS256}: RSA PKCS#1 v1.5 with SHA-256</li>
|
||||
* <li>{@link TokenAlgorithm#RS384}: RSA PKCS#1 v1.5 with SHA-384</li>
|
||||
* <li>{@link TokenAlgorithm#RS512}: RSA PKCS#1 v1.5 with SHA-512</li>
|
||||
* <li>{@link TokenAlgorithm#ES256}: ECDSA with SHA-256</li>
|
||||
* <li>{@link TokenAlgorithm#ES384}: ECDSA with SHA-384</li>
|
||||
* <li>{@link TokenAlgorithm#ES512}: ECDSA with SHA-512</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public enum TokenAlgorithm {
|
||||
|
||||
/**
|
||||
* HMAC using SHA-256
|
||||
*/
|
||||
HS256,
|
||||
|
||||
/**
|
||||
* HMAC using SHA-384
|
||||
*/
|
||||
HS384,
|
||||
|
||||
/**
|
||||
* HMAC using SHA-512
|
||||
*/
|
||||
HS512,
|
||||
|
||||
/**
|
||||
* RSASSA-PKCS-v1_5 using SHA-256
|
||||
*/
|
||||
RS256,
|
||||
|
||||
/**
|
||||
* RSASSA-PKCS-v1_5 using SHA-384
|
||||
*/
|
||||
RS384,
|
||||
|
||||
/**
|
||||
* RSASSA-PKCS-v1_5 using SHA-512
|
||||
*/
|
||||
RS512,
|
||||
|
||||
/**
|
||||
* ECDSA using P-256 and SHA-256
|
||||
*/
|
||||
ES256,
|
||||
|
||||
/**
|
||||
* ECDSA using P-384 and SHA-384
|
||||
*/
|
||||
ES384,
|
||||
|
||||
/**
|
||||
* ECDSA using P-521 and SHA-512
|
||||
*/
|
||||
ES512,
|
||||
;
|
||||
|
||||
/**
|
||||
* HMAC-based algorithms.
|
||||
*/
|
||||
public static final List<TokenAlgorithm> HMAC_ALGORITHMS = List.of(
|
||||
TokenAlgorithm.HS256, TokenAlgorithm.HS384, TokenAlgorithm.HS512
|
||||
);
|
||||
|
||||
/**
|
||||
* ECDSA-based algorithms.
|
||||
*/
|
||||
public static final List<TokenAlgorithm> ECDSA_ALGORITHMS = List.of(
|
||||
TokenAlgorithm.ES256, TokenAlgorithm.ES384, TokenAlgorithm.ES512
|
||||
);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.constants;
|
||||
|
||||
/**
|
||||
* The base data types used to process enum data.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
*/
|
||||
public enum TokenDataType {
|
||||
|
||||
/**
|
||||
* Marks enumeration being processed as Boolean.
|
||||
*/
|
||||
BOOLEAN(Boolean.class),
|
||||
|
||||
/**
|
||||
* Marks enumeration being processed as Double.
|
||||
*/
|
||||
DOUBLE(Long.class),
|
||||
|
||||
/**
|
||||
* Marks enumeration being processed as Float.
|
||||
*/
|
||||
FLOAT(Float.class),
|
||||
|
||||
/**
|
||||
* Marks enumeration being processed as Integer.
|
||||
*/
|
||||
INTEGER(Integer.class),
|
||||
|
||||
/**
|
||||
* Marks enumeration being processed as Long.
|
||||
*/
|
||||
LONG(Long.class),
|
||||
|
||||
/**
|
||||
* Marks enumeration being processed as String.
|
||||
*/
|
||||
STRING(String.class),
|
||||
;
|
||||
|
||||
/**
|
||||
* The mapped class to this mark.
|
||||
*/
|
||||
private final Class<?> mappedClass;
|
||||
|
||||
/**
|
||||
* Create a TokenDataType with a mapped class.
|
||||
*/
|
||||
TokenDataType(Class<?> mappedClass) {
|
||||
this.mappedClass = mappedClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the target mapped class.
|
||||
*
|
||||
* @return mapped class
|
||||
*/
|
||||
public Class<?> getMappedClass() {
|
||||
return mappedClass;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.exceptions;
|
||||
|
||||
/**
|
||||
* {@link IllegalKeyPairException} indicates an exception that the key pair is invalid.
|
||||
*
|
||||
* @author zihluwang
|
||||
* @version 1.6.0
|
||||
*/
|
||||
public class IllegalKeyPairException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Create a default exception instance.
|
||||
*/
|
||||
public IllegalKeyPairException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exception instance with specific message.
|
||||
*
|
||||
* @param message the message of the exception
|
||||
*/
|
||||
public IllegalKeyPairException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exception instance with specific message and cause.
|
||||
*
|
||||
* @param message the message of the exception
|
||||
* @param cause the cause of the exception
|
||||
*/
|
||||
public IllegalKeyPairException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.exceptions;
|
||||
|
||||
/**
|
||||
* {@link IllegalKeyPairException} indicates the secret to sign a JWT is illegal.
|
||||
*
|
||||
* @author zihluwang
|
||||
* @version 1.6.0
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public class IllegalSecretException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Create a default exception instance.
|
||||
*/
|
||||
public IllegalSecretException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exception instance with specific message.
|
||||
*
|
||||
* @param message the message of the exception
|
||||
*/
|
||||
public IllegalSecretException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exception instance with specific message and the cause of this exception.
|
||||
*
|
||||
* @param message the message of the exception
|
||||
* @param cause the cause of the exception
|
||||
*/
|
||||
public IllegalSecretException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.exceptions;
|
||||
|
||||
import com.onixbyte.simplejwt.TokenResolver;
|
||||
|
||||
/**
|
||||
* This {@code UnsupportedAlgorithmException} represents the given
|
||||
* algorithm is not supported by {@link
|
||||
* TokenResolver} yet.
|
||||
* <p>
|
||||
* If you want the supports to an unsupported algorithm, you could
|
||||
* <ul>
|
||||
* <li>Commit an issue at GitHub Issues or;</li>
|
||||
* <li>Communicate with us on Discord Community.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class UnsupportedAlgorithmException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnsupportedAlgorithmException} with {@code null}
|
||||
* as its detail message. The cause is not initialized, and may
|
||||
* subsequently be initialized by a call to {@link #initCause}.
|
||||
*/
|
||||
public UnsupportedAlgorithmException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnsupportedAlgorithmException} with the
|
||||
* specified detail message. The cause is not initialized, and may
|
||||
* subsequently be initialized by a call to {@link #initCause}.
|
||||
*
|
||||
* @param message the detail message. The detail message is saved for
|
||||
* later retrieval by the {@link #getMessage()} method.
|
||||
*/
|
||||
public UnsupportedAlgorithmException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnsupportedAlgorithmException} with the
|
||||
* specified detail message and cause.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval
|
||||
* by the {@link #getMessage()} method).
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A {@code null} value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public UnsupportedAlgorithmException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnsupportedAlgorithmException} with the
|
||||
* specified cause and a detail message of
|
||||
* {@code (cause==null ? null : cause.toString())} (which typically
|
||||
* contains the class and detail message of {@code cause}). This
|
||||
* constructor is useful for runtime exceptions that are little more
|
||||
* than wrappers for other throwable.
|
||||
*
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A {@code null} value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public UnsupportedAlgorithmException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code UnsupportedAlgorithmException} with the
|
||||
* specified detail message, cause, suppression enabled or disabled, and
|
||||
* writable stack trace enabled or disabled.
|
||||
*
|
||||
* @param message the detail message.
|
||||
* @param cause the cause (A {@code null} value is permitted,
|
||||
* and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @param enableSuppression whether suppression is enabled or disabled
|
||||
* @param writableStackTrace whether the stack trace should be writable
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public UnsupportedAlgorithmException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 OnixByte.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.onixbyte.simplejwt.exceptions;
|
||||
|
||||
/**
|
||||
* {@code WeakSecretException} represents that your secret is too weak to be
|
||||
* used in signing JWTs.
|
||||
* <p>
|
||||
* {@code WeakSecretException} will only appears that if you are using the
|
||||
* implementation module {@code cn.org.codecrafters:simple-jwt-jjwt} due to
|
||||
* it is implemented by {@code io.jsonwebtoken:jjwt}.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.1.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class WeakSecretException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WeakSecretException} with {@code null} as its
|
||||
* detail message. The cause is not initialized, and may subsequently be
|
||||
* initialized by a call to {@link #initCause}.
|
||||
*/
|
||||
public WeakSecretException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WeakSecretException} with the specified detail
|
||||
* message. The cause is not initialized, and may subsequently be
|
||||
* initialized by a call to {@link #initCause}.
|
||||
*
|
||||
* @param message the detail message. The detail message is saved for
|
||||
* later retrieval by the {@link #getMessage()} method.
|
||||
*/
|
||||
public WeakSecretException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WeakSecretException} with the specified detail
|
||||
* message and cause.
|
||||
* <p>
|
||||
* Note that the detail message associated with {@code cause} is <i>not</i>
|
||||
* automatically incorporated in this runtime exception's detail message.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval
|
||||
* by the {@link #getMessage()} method).
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A {@code null} value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public WeakSecretException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WeakSecretException} with the specified cause
|
||||
* and a detail message of {@code (cause==null ? null : cause.toString())}
|
||||
* (which typically contains the class and detail message of
|
||||
* {@code cause}). This constructor is useful for runtime exceptions that
|
||||
* are little more than wrappers for other throwable.
|
||||
*
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A {@code null} value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public WeakSecretException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code WeakSecretException} with the specified detail
|
||||
* message, cause, suppression enabled or disabled, and writable
|
||||
* stack trace enabled or disabled.
|
||||
*
|
||||
* @param message the detail message.
|
||||
* @param cause the cause. (A {@code null} value is permitted,
|
||||
* and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @param enableSuppression whether suppression is enabled or disabled
|
||||
* @param writableStackTrace whether the stack trace should be writable
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public WeakSecretException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023-2024 OnixByte.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
<property name="COLOURFUL_OUTPUT" value="%black(%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK}) %highlight(%-5level) %black(---) %black([%10.10t]) %cyan(%-20.20logger{20}) %black(:) %msg%n"/>
|
||||
<property name="STANDARD_OUTPUT" value="%date{'dd MMM, yyyy HH:mm:ss', Asia/Hong_Kong, en-UK} %-5level %black(---) [%10.10t] %-20.20logger{20} : %msg%n"/>
|
||||
|
||||
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>${COLOURFUL_OUTPUT}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user