Skip to content

Commit

Permalink
fix: Make JwtTokenValidator not a bean (#1848)
Browse files Browse the repository at this point in the history
* fix: Make JwtTokenValidator not a bean

- remove `@Inject` so JwtTokenValidator will no longer be a bean candidate
- allow disabling NimbusReactiveJsonWebTokenValidator in case of custom implementation

* add configuration properties for validator

* javadoc: remove unused imports

---------

Co-authored-by: Sergio del Amo <sergio.delamo@softamo.com>
  • Loading branch information
kevin-wise and sdelamo authored Nov 13, 2024
1 parent 6c47864 commit 99d6002
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.util.StringUtils;
import io.micronaut.security.token.jwt.signature.ReactiveSignatureConfiguration;
import io.micronaut.security.token.jwt.signature.SignatureConfiguration;
import io.micronaut.security.token.jwt.validator.GenericJwtClaimsValidator;
Expand All @@ -38,6 +40,7 @@
* @param <R> Request
*/
@Singleton
@Requires(property = NimbusJsonWebTokenValidatorConfigurationProperties.PREFIX + ".validator", value = StringUtils.TRUE, defaultValue = StringUtils.TRUE)
class NimbusJsonWebTokenValidator<R> extends AbstractJsonWebTokenValidator<R> implements JsonWebTokenValidator<JWT, R> {
private final JsonWebTokenParser<JWT> jsonWebTokenParser;
private final JsonWebTokenSignatureValidator<SignedJWT> signatureValidator;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2017-2024 original authors
*
* 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
*
* https://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 io.micronaut.security.token.jwt.nimbus;

/**
* Nimbus Json Web Token Validators Configuration.
* @author Sergio del Amo
* @since 4.11.1
*/
public interface NimbusJsonWebTokenValidatorConfiguration {
/**
*
* @return Whether the bean {@link NimbusReactiveJsonWebTokenValidator} is enabled.
*/
boolean isReactiveValidator();

/**
*
* @return Whether the bean {@link NimbusJsonWebTokenValidator} is enabled.
*/
boolean isValidator();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2017-2024 original authors
*
* 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
*
* https://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 io.micronaut.security.token.jwt.nimbus;

import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.security.token.jwt.config.JwtConfigurationProperties;

/**
* {@link ConfigurationProperties} implementation of {@link NimbusJsonWebTokenValidatorConfiguration}.
* @author Sergio del Amo
* @since 4.11.1
*/
@ConfigurationProperties(NimbusJsonWebTokenValidatorConfigurationProperties.PREFIX)
public class NimbusJsonWebTokenValidatorConfigurationProperties implements NimbusJsonWebTokenValidatorConfiguration {
/**
* The default reactive validator value.
*/
@SuppressWarnings("WeakerAccess")
public static final String PREFIX = JwtConfigurationProperties.PREFIX + ".nimbus";

/**
* The default reactive validator value.
*/
@SuppressWarnings("WeakerAccess")
public static final boolean DEFAULT_REACTIVE_VALIDATOR = true;

/**
* The default enable value.
*/
@SuppressWarnings("WeakerAccess")
public static final boolean DEFAULT_VALIDATOR = true;

private boolean reactiveValidator = DEFAULT_REACTIVE_VALIDATOR;
private boolean validator = DEFAULT_VALIDATOR;

@Override
public boolean isReactiveValidator() {
return reactiveValidator;
}

@Override
public boolean isValidator() {
return validator;
}

/**
* Whether the bean {@link NimbusReactiveJsonWebTokenValidator} is enabled. Default value {@value #DEFAULT_REACTIVE_VALIDATOR}.
* @param reactiveValidator Whether the bean {@link NimbusReactiveJsonWebTokenValidator} is enabled.
*/
public void setReactiveValidator(boolean reactiveValidator) {
this.reactiveValidator = reactiveValidator;
}

/**
* Whether the bean {@link NimbusJsonWebTokenValidator} is enabled. Default value {@value #DEFAULT_VALIDATOR}.
* @param validator Whether the bean {@link NimbusJsonWebTokenValidator} is enabled.
*/
public void setValidator(boolean validator) {
this.validator = validator;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.async.annotation.SingleResult;
import io.micronaut.core.util.StringUtils;
import io.micronaut.security.authentication.Authentication;
import io.micronaut.security.token.jwt.signature.ReactiveSignatureConfiguration;
import io.micronaut.security.token.jwt.signature.SignatureConfiguration;
Expand All @@ -43,6 +45,7 @@
* @param <R> The request type
*/
@Singleton
@Requires(property = NimbusJsonWebTokenValidatorConfigurationProperties.PREFIX + ".reactive-validator", value = StringUtils.TRUE, defaultValue = StringUtils.TRUE)
class NimbusReactiveJsonWebTokenValidator<R> extends AbstractJsonWebTokenValidator<R> implements ReactiveJsonWebTokenValidator<JWT, R> {
private final JwtAuthenticationFactory jwtAuthenticationFactory;
private final JsonWebTokenParser<JWT> jsonWebTokenParser;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import io.micronaut.security.token.jwt.encryption.EncryptionConfiguration;
import io.micronaut.security.token.jwt.signature.SignatureConfiguration;
import io.micronaut.security.token.validator.TokenValidator;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
Expand Down Expand Up @@ -55,7 +54,6 @@ public class JwtTokenValidator<T> implements TokenValidator<T> {
* @param jwtAuthenticationFactory Utility to generate an Authentication given a JWT.
* @param executorService Executor Service
*/
@Inject
public JwtTokenValidator(Collection<SignatureConfiguration> signatureConfigurations,
Collection<EncryptionConfiguration> encryptionConfigurations,
Collection<GenericJwtClaimsValidator> genericJwtClaimsValidators,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.micronaut.security.token.validator

import io.micronaut.context.BeanContext
import io.micronaut.context.annotation.Property
import io.micronaut.core.util.StringUtils
import io.micronaut.security.token.jwt.nimbus.NimbusJsonWebTokenValidator
import io.micronaut.security.token.jwt.nimbus.NimbusReactiveJsonWebTokenValidator
import io.micronaut.security.token.jwt.validator.JsonWebTokenValidator
import io.micronaut.security.token.jwt.validator.JwtTokenValidator
import io.micronaut.security.token.jwt.validator.ReactiveJsonWebTokenValidator
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification


@MicronautTest(startApplication = false, rebuildContext = true)
class TokenValidatorSpec extends Specification {

@Inject
Collection<TokenValidator> tokenValidators

@Inject
BeanContext beanContext

void "JwtTokenValidator should not be considered a bean by default"() {
expect:
tokenValidators.stream().noneMatch {it instanceof JwtTokenValidator}
}

void "NimbusReactiveJsonWebTokenValidator should be considered a bean by default"() {
expect:
tokenValidators.size() == 1
tokenValidators.stream().anyMatch {it.getClass().getSimpleName() == "NimbusReactiveJsonWebTokenValidator"}
}

@Property(name = "micronaut.security.token.jwt.nimbus.reactive-validator", value = StringUtils.FALSE)
void "NimbusReactiveJsonWebTokenValidator can be disabled via config"() {
expect:
tokenValidators.stream().noneMatch {it.getClass().getSimpleName() == "NimbusReactiveJsonWebTokenValidator"}
!beanContext.containsBean(ReactiveJsonWebTokenValidator)
!beanContext.containsBean(NimbusReactiveJsonWebTokenValidator)
beanContext.containsBean(JsonWebTokenValidator)
}

@Property(name = "micronaut.security.token.jwt.nimbus.validator", value = StringUtils.FALSE)
void "NimbusJsonWebTokenValidator can be disabled via config"() {
expect:
!beanContext.containsBean(JsonWebTokenValidator)
!beanContext.containsBean(NimbusJsonWebTokenValidator)
beanContext.containsBean(ReactiveJsonWebTokenValidator)
}
}

0 comments on commit 99d6002

Please sign in to comment.