feat: added ECDSA-based algorithm support

make the simple-jwt auth0 implementation can use ECDSA-based algorithms

BREAKING CHANGE: the io.jsonwebtoken:jjwt implementation was
discontinued since its design made a big challenge to encapsulation
This commit is contained in:
zihluwang
2024-08-06 22:02:00 +08:00
parent 62b8cb8118
commit fe88788611
21 changed files with 344 additions and 1477 deletions
@@ -23,7 +23,7 @@ import com.onixbyte.simplejwt.authzero.AuthzeroTokenResolver;
import com.onixbyte.simplejwt.autoconfiguration.properties.SimpleJwtProperties;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.onixbyte.simplejwt.config.TokenResolverConfig;
import com.onixbyte.simplejwt.constants.TokenAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -91,25 +91,21 @@ public class AuthzeroTokenResolverAutoConfiguration {
*/
@Bean
public TokenResolver<DecodedJWT> tokenResolver() {
if (TokenResolverConfig.HMAC_ALGORITHMS.contains(simpleJwtProperties.algorithm())) {
return new AuthzeroTokenResolver(
jtiCreator,
simpleJwtProperties.algorithm(),
simpleJwtProperties.issuer(),
simpleJwtProperties.secret(),
"",
objectMapper
);
} else {
return new AuthzeroTokenResolver(
jtiCreator,
simpleJwtProperties.algorithm(),
simpleJwtProperties.issuer(),
simpleJwtProperties.getPrivateKey(),
simpleJwtProperties.getPublicKey(),
objectMapper
);
var builder = AuthzeroTokenResolver.builder();
if (TokenAlgorithm.HMAC_ALGORITHMS.contains(simpleJwtProperties.getAlgorithm())) {
builder.keyPair(simpleJwtProperties.getPublicKey(), simpleJwtProperties.getPrivateKey())
.algorithm(simpleJwtProperties.getAlgorithm());
} else if (TokenAlgorithm.ECDSA_ALGORITHMS.contains(simpleJwtProperties.getAlgorithm())) {
builder.secret(simpleJwtProperties.getSecret())
.algorithm(simpleJwtProperties.getAlgorithm());
}
builder.issuer(simpleJwtProperties.getIssuer());
builder.jtiCreator(jtiCreator);
builder.objectMapper(objectMapper);
return builder.build();
}
private final GuidCreator<?> jtiCreator;
@@ -1,110 +0,0 @@
/*
* Copyright (C) 2024-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.
*/
package com.onixbyte.simplejwt.autoconfiguration;
import com.onixbyte.guid.GuidCreator;
import com.onixbyte.simplejwt.TokenResolver;
import com.onixbyte.simplejwt.autoconfiguration.properties.SimpleJwtProperties;
import com.onixbyte.simplejwt.jjwt.JjwtTokenResolver;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* {@code JjwtTokenResolverAutoConfiguration} is responsible for automatically
* configuring the Simple JWT library with {@code io.jsonwebtoken:jjwt-api}
* when used in a Spring Boot application. It provides default settings and
* configurations to ensure that the library works smoothly without requiring
* manual configuration.
* <p>
* This autoconfiguration class sets up the necessary beans and components
* required for JWT generation and validation. It automatically creates and
* configures the {@link JjwtTokenResolver} bean based on the available options
* and properties.
* <p>
* Developers using the Simple JWT library with Spring Boot do not need to
* explicitly configure the library, as the autoconfiguration takes care of
* setting up the necessary components and configurations automatically.
* However, developers still have the flexibility to customize the behavior of
* the library by providing their own configurations and properties.
*
* @author Zihlu Wang
* @version 1.1.0
* @since 1.0.0
*/
@Slf4j
@AutoConfiguration
@EnableConfigurationProperties(value = {SimpleJwtProperties.class})
@ConditionalOnClass({Jws.class, Claims.class, JjwtTokenResolver.class})
@ConditionalOnMissingBean({TokenResolver.class})
@ConditionalOnBean(value = {GuidCreator.class}, name = "jtiCreator")
@AutoConfigureAfter(value = GuidAutoConfiguration.class)
public class JjwtTokenResolverAutoConfiguration {
/**
* Constructs a new {@code SimpleJwtAutoConfiguration} instance with the provided
* {@link SimpleJwtProperties}.
*
* @param jtiCreator a creator to create JSON Web Token ids
* @param simpleJwtProperties the SimpleJwtProperties instance
*/
@Autowired
public JjwtTokenResolverAutoConfiguration(SimpleJwtProperties simpleJwtProperties, @Qualifier("jtiCreator") GuidCreator<?> jtiCreator) {
this.jtiCreator = jtiCreator;
this.simpleJwtProperties = simpleJwtProperties;
}
/**
* Creates a new {@link TokenResolver} bean using {@link JjwtTokenResolver} if no existing
* {@link TokenResolver} bean is found. The {@link JjwtTokenResolver} is configured with the
* provided {@link GuidCreator}, {@code algorithm}, {@code issuer}, and {@code secret}
* properties from {@link SimpleJwtProperties}.
*
* @return the {@link TokenResolver} instance
*/
@Bean
public TokenResolver<Jws<Claims>> tokenResolver() {
return new JjwtTokenResolver(
jtiCreator,
simpleJwtProperties.algorithm(),
simpleJwtProperties.issuer(),
simpleJwtProperties.secret()
);
}
/**
* The GuidCreator instance to be used for generating JWT IDs (JTI).
*/
private final GuidCreator<?> jtiCreator;
/**
* The {@code SimpleJwtProperties} instance containing the configuration properties
* for Simple JWT.
*/
private final SimpleJwtProperties simpleJwtProperties;
}
@@ -20,7 +20,6 @@ package com.onixbyte.simplejwt.autoconfiguration.properties;
import com.onixbyte.simplejwt.SecretCreator;
import com.onixbyte.simplejwt.autoconfiguration.AuthzeroTokenResolverAutoConfiguration;
import com.onixbyte.simplejwt.constants.TokenAlgorithm;
import com.onixbyte.simplejwt.jjwt.JjwtTokenResolver;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -31,9 +30,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* "onixbyte.simple-jwt".
* <p>
* {@code SimpleJwtProperties} provides configuration options for the JWT algorithm, issuer,
* and secret. The properties are used by the {@link AuthzeroTokenResolverAutoConfiguration} and
* {@link JjwtTokenResolver} to set up the necessary configurations for JWT generation
* and validation.
* and secret. The properties are used by the {@link AuthzeroTokenResolverAutoConfiguration} to
* set up the necessary configurations for JWT generation and validation.
* <p>
* Developers can customise the JWT algorithm, issuer, and secret by setting the corresponding
* properties in the application's properties file. The {@code SimpleJwtAutoConfiguration} class
@@ -72,38 +70,14 @@ public class SimpleJwtProperties {
private String secret = SecretCreator.createSecret(32, true, true, true);
/**
* The private key of
* The private key, PEM formatted.
*/
private String privateKey;
/**
* The public key, PEM formatted
*/
private String publicKey;
/**
* Returns the JWT algorithm configured in the properties.
*
* @return the JWT algorithm
*/
public final TokenAlgorithm algorithm() {
return algorithm;
}
/**
* Returns the issuer value configured in the properties.
*
* @return the issuer value
*/
public final String issuer() {
return issuer;
}
/**
* Returns the secret key configured in the properties.
*
* @return the secret key
*/
public final String secret() {
return secret;
}
}