Extract the ID Token JwtDecoderFactory to enable user customization
This commit ensures that the JwtDecoderFactory is not a private field inside the Oidc authentication provider by extracting this class and giving the possibility to customize the way different providers are validated. Fixes: gh-6379
This commit is contained in:
parent
dd45a49f02
commit
fe5f10e9a2
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -27,11 +27,9 @@ import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
|
|||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
|
||||
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
|
||||
|
@ -43,16 +41,10 @@ import org.springframework.security.oauth2.jwt.Jwt;
|
|||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoderFactory;
|
||||
import org.springframework.security.oauth2.jwt.JwtException;
|
||||
import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.springframework.security.oauth2.jwt.JwtProcessors.withJwkSetUri;
|
||||
|
||||
/**
|
||||
* An implementation of an {@link AuthenticationProvider}
|
||||
|
@ -82,10 +74,9 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati
|
|||
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
||||
private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
|
||||
private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token";
|
||||
private static final String MISSING_SIGNATURE_VERIFIER_ERROR_CODE = "missing_signature_verifier";
|
||||
private final OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
|
||||
private final OAuth2UserService<OidcUserRequest, OidcUser> userService;
|
||||
private JwtDecoderFactory<ClientRegistration> jwtDecoderFactory = new DefaultJwtDecoderFactory();
|
||||
private JwtDecoderFactory<ClientRegistration> jwtDecoderFactory = new OidcIdTokenDecoderFactory();
|
||||
private GrantedAuthoritiesMapper authoritiesMapper = (authorities -> authorities);
|
||||
|
||||
/**
|
||||
|
@ -219,30 +210,4 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati
|
|||
OidcIdToken idToken = new OidcIdToken(jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaims());
|
||||
return idToken;
|
||||
}
|
||||
|
||||
private static class DefaultJwtDecoderFactory implements JwtDecoderFactory<ClientRegistration> {
|
||||
private final Map<String, JwtDecoder> jwtDecoders = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public JwtDecoder createDecoder(ClientRegistration clientRegistration) {
|
||||
return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), key -> {
|
||||
if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) {
|
||||
OAuth2Error oauth2Error = new OAuth2Error(
|
||||
MISSING_SIGNATURE_VERIFIER_ERROR_CODE,
|
||||
"Failed to find a Signature Verifier for Client Registration: '" +
|
||||
clientRegistration.getRegistrationId() +
|
||||
"'. Check to ensure you have configured the JwkSet URI.",
|
||||
null
|
||||
);
|
||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||
}
|
||||
String jwkSetUri = clientRegistration.getProviderDetails().getJwkSetUri();
|
||||
NimbusJwtDecoder jwtDecoder = new NimbusJwtDecoder(withJwkSetUri(jwkSetUri).build());
|
||||
OAuth2TokenValidator<Jwt> jwtValidator = new DelegatingOAuth2TokenValidator<>(
|
||||
new JwtTimestampValidator(), new OidcIdTokenValidator(clientRegistration));
|
||||
jwtDecoder.setJwtValidator(jwtValidator);
|
||||
return jwtDecoder;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -26,12 +26,10 @@ import org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessT
|
|||
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.userinfo.ReactiveOAuth2UserService;
|
||||
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthorizationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponse;
|
||||
|
@ -39,19 +37,14 @@ import org.springframework.security.oauth2.core.oidc.OidcIdToken;
|
|||
import org.springframework.security.oauth2.core.oidc.endpoint.OidcParameterNames;
|
||||
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtException;
|
||||
import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
|
||||
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoderFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* An implementation of an {@link org.springframework.security.authentication.AuthenticationProvider} for OAuth 2.0 Login,
|
||||
|
@ -83,7 +76,6 @@ public class OidcAuthorizationCodeReactiveAuthenticationManager implements
|
|||
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
|
||||
private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
|
||||
private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token";
|
||||
private static final String MISSING_SIGNATURE_VERIFIER_ERROR_CODE = "missing_signature_verifier";
|
||||
|
||||
private final ReactiveOAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
|
||||
|
||||
|
@ -91,7 +83,7 @@ public class OidcAuthorizationCodeReactiveAuthenticationManager implements
|
|||
|
||||
private GrantedAuthoritiesMapper authoritiesMapper = (authorities -> authorities);
|
||||
|
||||
private ReactiveJwtDecoderFactory<ClientRegistration> jwtDecoderFactory = new DefaultJwtDecoderFactory();
|
||||
private ReactiveJwtDecoderFactory<ClientRegistration> jwtDecoderFactory = new ReactiveOidcIdTokenDecoderFactory();
|
||||
|
||||
public OidcAuthorizationCodeReactiveAuthenticationManager(
|
||||
ReactiveOAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient,
|
||||
|
@ -199,30 +191,4 @@ public class OidcAuthorizationCodeReactiveAuthenticationManager implements
|
|||
return jwtDecoder.decode(rawIdToken)
|
||||
.map(jwt -> new OidcIdToken(jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaims()));
|
||||
}
|
||||
|
||||
private static class DefaultJwtDecoderFactory implements ReactiveJwtDecoderFactory<ClientRegistration> {
|
||||
private final Map<String, ReactiveJwtDecoder> jwtDecoders = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public ReactiveJwtDecoder createDecoder(ClientRegistration clientRegistration) {
|
||||
return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), key -> {
|
||||
if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) {
|
||||
OAuth2Error oauth2Error = new OAuth2Error(
|
||||
MISSING_SIGNATURE_VERIFIER_ERROR_CODE,
|
||||
"Failed to find a Signature Verifier for Client Registration: '" +
|
||||
clientRegistration.getRegistrationId() +
|
||||
"'. Check to ensure you have configured the JwkSet URI.",
|
||||
null
|
||||
);
|
||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||
}
|
||||
NimbusReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder(
|
||||
clientRegistration.getProviderDetails().getJwkSetUri());
|
||||
OAuth2TokenValidator<Jwt> jwtValidator = new DelegatingOAuth2TokenValidator<>(
|
||||
new JwtTimestampValidator(), new OidcIdTokenValidator(clientRegistration));
|
||||
jwtDecoder.setJwtValidator(jwtValidator);
|
||||
return jwtDecoder;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or 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
|
||||
*
|
||||
* 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 org.springframework.security.oauth2.client.oidc.authentication;
|
||||
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoderFactory;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.springframework.security.oauth2.jwt.JwtProcessors.withJwkSetUri;
|
||||
|
||||
/**
|
||||
* Provides a default or custom implementation for {@link OAuth2TokenValidator}
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @author Rafael Dominguez
|
||||
* @since 5.2
|
||||
*
|
||||
* @see OAuth2TokenValidator
|
||||
* @see Jwt
|
||||
*/
|
||||
public final class OidcIdTokenDecoderFactory implements JwtDecoderFactory<ClientRegistration> {
|
||||
private static final String MISSING_SIGNATURE_VERIFIER_ERROR_CODE = "missing_signature_verifier";
|
||||
private final Map<String, JwtDecoder> jwtDecoders = new ConcurrentHashMap<>();
|
||||
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> jwtValidatorFactory = OidcIdTokenValidator::new;
|
||||
|
||||
@Override
|
||||
public JwtDecoder createDecoder(ClientRegistration clientRegistration) {
|
||||
Assert.notNull(clientRegistration, "clientRegistration cannot be null.");
|
||||
return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), key -> {
|
||||
if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) {
|
||||
OAuth2Error oauth2Error = new OAuth2Error(
|
||||
MISSING_SIGNATURE_VERIFIER_ERROR_CODE,
|
||||
"Failed to find a Signature Verifier for Client Registration: '" +
|
||||
clientRegistration.getRegistrationId() +
|
||||
"'. Check to ensure you have configured the JwkSet URI.",
|
||||
null
|
||||
);
|
||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||
}
|
||||
String jwkSetUri = clientRegistration.getProviderDetails().getJwkSetUri();
|
||||
NimbusJwtDecoder jwtDecoder = new NimbusJwtDecoder(withJwkSetUri(jwkSetUri).build());
|
||||
OAuth2TokenValidator<Jwt> jwtValidator = jwtValidatorFactory.apply(clientRegistration);
|
||||
jwtDecoder.setJwtValidator(jwtValidator);
|
||||
return jwtDecoder;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows user customization for the {@link OAuth2TokenValidator}
|
||||
*
|
||||
* @param jwtValidatorFactory
|
||||
*/
|
||||
public final void setJwtValidatorFactory(Function<ClientRegistration, OAuth2TokenValidator<Jwt>> jwtValidatorFactory) {
|
||||
Assert.notNull(jwtValidatorFactory, "jwtValidatorFactory cannot be null.");
|
||||
this.jwtValidatorFactory = jwtValidatorFactory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or 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
|
||||
*
|
||||
* 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 org.springframework.security.oauth2.client.oidc.authentication;
|
||||
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoderFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Provides a default or custom reactive implementation for {@link OAuth2TokenValidator}
|
||||
*
|
||||
* @author Joe Grandja
|
||||
* @author Rafael Dominguez
|
||||
* @since 5.2
|
||||
*
|
||||
* @see OAuth2TokenValidator
|
||||
* @see Jwt
|
||||
*/
|
||||
public final class ReactiveOidcIdTokenDecoderFactory implements ReactiveJwtDecoderFactory<ClientRegistration> {
|
||||
private static final String MISSING_SIGNATURE_VERIFIER_ERROR_CODE = "missing_signature_verifier";
|
||||
private final Map<String, ReactiveJwtDecoder> jwtDecoders = new ConcurrentHashMap<>();
|
||||
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> jwtValidatorFactory = OidcIdTokenValidator::new;
|
||||
|
||||
@Override
|
||||
public ReactiveJwtDecoder createDecoder(ClientRegistration clientRegistration) {
|
||||
Assert.notNull(clientRegistration, "clientRegistration cannot be null.");
|
||||
return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), key -> {
|
||||
if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) {
|
||||
OAuth2Error oauth2Error = new OAuth2Error(
|
||||
MISSING_SIGNATURE_VERIFIER_ERROR_CODE,
|
||||
"Failed to find a Signature Verifier for Client Registration: '" +
|
||||
clientRegistration.getRegistrationId() +
|
||||
"'. Check to ensure you have configured the JwkSet URI.",
|
||||
null
|
||||
);
|
||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||
}
|
||||
NimbusReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder(
|
||||
clientRegistration.getProviderDetails().getJwkSetUri());
|
||||
OAuth2TokenValidator<Jwt> jwtValidator = jwtValidatorFactory.apply(clientRegistration);
|
||||
jwtDecoder.setJwtValidator(jwtValidator);
|
||||
return jwtDecoder;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows user customization for the {@link OAuth2TokenValidator}
|
||||
*
|
||||
* @param jwtValidatorFactory
|
||||
*/
|
||||
public final void setJwtValidatorFactory(Function<ClientRegistration, OAuth2TokenValidator<Jwt>> jwtValidatorFactory) {
|
||||
Assert.notNull(jwtValidatorFactory, "jwtValidatorFactory cannot be null.");
|
||||
this.jwtValidatorFactory = jwtValidatorFactory;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or 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
|
||||
*
|
||||
* 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 org.springframework.security.oauth2.client.oidc.authentication;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Joe Grandja
|
||||
* @author Rafael Dominguez
|
||||
* @since 5.2
|
||||
*/
|
||||
public class OidcIdTokenDecoderFactoryTests {
|
||||
|
||||
private ClientRegistration.Builder registration = TestClientRegistrations.clientRegistration()
|
||||
.scope("openid");
|
||||
|
||||
private OidcIdTokenDecoderFactory idTokenDecoderFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
idTokenDecoderFactory = new OidcIdTokenDecoderFactory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setJwtValidatorFactoryWhenNullThenThrowIllegalArgumentException(){
|
||||
assertThatThrownBy(()-> idTokenDecoderFactory.setJwtValidatorFactory(null))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenClientRegistrationNullThenThrowIllegalArgumentException(){
|
||||
assertThatThrownBy(() -> idTokenDecoderFactory.createDecoder(null))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenJwkSetUriEmptyThenThrowOAuth2AuthenticationException(){
|
||||
assertThatThrownBy(()-> idTokenDecoderFactory.createDecoder(registration.jwkSetUri(null).build()))
|
||||
.isInstanceOf(OAuth2AuthenticationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenClientRegistrationValidThenReturnDecoder(){
|
||||
assertThat(idTokenDecoderFactory.createDecoder(registration.build()))
|
||||
.isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenCustomJwtValidatorFactorySetThenApplied(){
|
||||
Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customValidator = mock(Function.class);
|
||||
idTokenDecoderFactory.setJwtValidatorFactory(customValidator);
|
||||
|
||||
when(customValidator.apply(any(ClientRegistration.class)))
|
||||
.thenReturn(customJwtValidatorFactory.apply(registration.build()));
|
||||
|
||||
idTokenDecoderFactory.createDecoder(registration.build());
|
||||
|
||||
verify(customValidator).apply(any(ClientRegistration.class));
|
||||
}
|
||||
|
||||
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customJwtValidatorFactory = (c) -> {
|
||||
OidcIdTokenValidator idTokenValidator = new OidcIdTokenValidator(c);
|
||||
if (c.getRegistrationId().equals("registration-id1")) {
|
||||
idTokenValidator.setClockSkew(Duration.ofSeconds(30));
|
||||
} else if (c.getRegistrationId().equals("registration-id2")) {
|
||||
idTokenValidator.setClockSkew(Duration.ofSeconds(70));
|
||||
}
|
||||
return idTokenValidator;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or 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
|
||||
*
|
||||
* 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 org.springframework.security.oauth2.client.oidc.authentication;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.registration.TestClientRegistrations;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Joe Grandja
|
||||
* @author Rafael Dominguez
|
||||
* @since 5.2
|
||||
*/
|
||||
public class ReactiveOidcIdTokenDecoderFactoryTests {
|
||||
|
||||
private ClientRegistration.Builder registration = TestClientRegistrations.clientRegistration()
|
||||
.scope("openid");
|
||||
|
||||
private ReactiveOidcIdTokenDecoderFactory idTokenDecoderFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
idTokenDecoderFactory = new ReactiveOidcIdTokenDecoderFactory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setJwtValidatorFactoryWhenNullThenThrowIllegalArgumentException(){
|
||||
assertThatThrownBy(()-> idTokenDecoderFactory.setJwtValidatorFactory(null))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenClientRegistrationNullThenThrowIllegalArgumentException(){
|
||||
assertThatThrownBy(() -> idTokenDecoderFactory.createDecoder(null))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenJwkSetUriEmptyThenThrowOAuth2AuthenticationException(){
|
||||
assertThatThrownBy(()-> idTokenDecoderFactory.createDecoder(registration.jwkSetUri(null).build()))
|
||||
.isInstanceOf(OAuth2AuthenticationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenClientRegistrationValidThenReturnDecoder(){
|
||||
assertThat(idTokenDecoderFactory.createDecoder(registration.build()))
|
||||
.isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createDecoderWhenCustomJwtValidatorFactorySetThenApplied(){
|
||||
Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customValidator = mock(Function.class);
|
||||
idTokenDecoderFactory.setJwtValidatorFactory(customValidator);
|
||||
|
||||
when(customValidator.apply(any(ClientRegistration.class)))
|
||||
.thenReturn(customJwtValidatorFactory.apply(registration.build()));
|
||||
|
||||
idTokenDecoderFactory.createDecoder(registration.build());
|
||||
|
||||
verify(customValidator).apply(any(ClientRegistration.class));
|
||||
}
|
||||
|
||||
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customJwtValidatorFactory = (c) -> {
|
||||
OidcIdTokenValidator idTokenValidator = new OidcIdTokenValidator(c);
|
||||
if (c.getRegistrationId().equals("registration-id1")) {
|
||||
idTokenValidator.setClockSkew(Duration.ofSeconds(30));
|
||||
} else if (c.getRegistrationId().equals("registration-id2")) {
|
||||
idTokenValidator.setClockSkew(Duration.ofSeconds(70));
|
||||
}
|
||||
return idTokenValidator;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue