Skip to content

Commit 2a86799

Browse files
committed
Polish gh-6415
1 parent fe5f10e commit 2a86799

File tree

6 files changed

+67
-79
lines changed

6 files changed

+67
-79
lines changed

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeAuthenticationProvider.java

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
* @see OAuth2AccessTokenResponseClient
6767
* @see OidcUserService
6868
* @see OidcUser
69+
* @see OidcIdTokenDecoderFactory
6970
* @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth">Section 3.1 Authorization Code Grant Flow</a>
7071
* @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#TokenRequest">Section 3.1.3.1 Token Request</a>
7172
* @see <a target="_blank" href="http://openid.net/specs/openid-connect-core-1_0.html#TokenResponse">Section 3.1.3.3 Token Response</a>

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcAuthorizationCodeReactiveAuthenticationManager.java

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
* @see ReactiveOAuth2AccessTokenResponseClient
6767
* @see ReactiveOAuth2UserService
6868
* @see OAuth2User
69+
* @see ReactiveOidcIdTokenDecoderFactory
6970
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1">Section 4.1 Authorization Code Grant Flow</a>
7071
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.3">Section 4.1.3 Access Token Request</a>
7172
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.4">Section 4.1.4 Access Token Response</a>

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenDecoderFactory.java

+13-9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
2020
import org.springframework.security.oauth2.core.OAuth2Error;
2121
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
22+
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
2223
import org.springframework.security.oauth2.jwt.Jwt;
2324
import org.springframework.security.oauth2.jwt.JwtDecoder;
2425
import org.springframework.security.oauth2.jwt.JwtDecoderFactory;
@@ -33,14 +34,16 @@
3334
import static org.springframework.security.oauth2.jwt.JwtProcessors.withJwkSetUri;
3435

3536
/**
36-
* Provides a default or custom implementation for {@link OAuth2TokenValidator}
37+
* A {@link JwtDecoderFactory factory} that provides a {@link JwtDecoder}
38+
* used for {@link OidcIdToken} signature verification.
39+
* The provided {@link JwtDecoder} is associated to a specific {@link ClientRegistration}.
3740
*
3841
* @author Joe Grandja
3942
* @author Rafael Dominguez
4043
* @since 5.2
41-
*
42-
* @see OAuth2TokenValidator
43-
* @see Jwt
44+
* @see JwtDecoderFactory
45+
* @see ClientRegistration
46+
* @see OidcIdToken
4447
*/
4548
public final class OidcIdTokenDecoderFactory implements JwtDecoderFactory<ClientRegistration> {
4649
private static final String MISSING_SIGNATURE_VERIFIER_ERROR_CODE = "missing_signature_verifier";
@@ -49,7 +52,7 @@ public final class OidcIdTokenDecoderFactory implements JwtDecoderFactory<Client
4952

5053
@Override
5154
public JwtDecoder createDecoder(ClientRegistration clientRegistration) {
52-
Assert.notNull(clientRegistration, "clientRegistration cannot be null.");
55+
Assert.notNull(clientRegistration, "clientRegistration cannot be null");
5356
return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), key -> {
5457
if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) {
5558
OAuth2Error oauth2Error = new OAuth2Error(
@@ -63,19 +66,20 @@ public JwtDecoder createDecoder(ClientRegistration clientRegistration) {
6366
}
6467
String jwkSetUri = clientRegistration.getProviderDetails().getJwkSetUri();
6568
NimbusJwtDecoder jwtDecoder = new NimbusJwtDecoder(withJwkSetUri(jwkSetUri).build());
66-
OAuth2TokenValidator<Jwt> jwtValidator = jwtValidatorFactory.apply(clientRegistration);
69+
OAuth2TokenValidator<Jwt> jwtValidator = this.jwtValidatorFactory.apply(clientRegistration);
6770
jwtDecoder.setJwtValidator(jwtValidator);
6871
return jwtDecoder;
6972
});
7073
}
7174

7275
/**
73-
* Allows user customization for the {@link OAuth2TokenValidator}
76+
* Sets the factory that provides an {@link OAuth2TokenValidator}, which is used by the {@link JwtDecoder}.
77+
* The default is {@link OidcIdTokenValidator}.
7478
*
75-
* @param jwtValidatorFactory
79+
* @param jwtValidatorFactory the factory that provides an {@link OAuth2TokenValidator}
7680
*/
7781
public final void setJwtValidatorFactory(Function<ClientRegistration, OAuth2TokenValidator<Jwt>> jwtValidatorFactory) {
78-
Assert.notNull(jwtValidatorFactory, "jwtValidatorFactory cannot be null.");
82+
Assert.notNull(jwtValidatorFactory, "jwtValidatorFactory cannot be null");
7983
this.jwtValidatorFactory = jwtValidatorFactory;
8084
}
8185
}

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/ReactiveOidcIdTokenDecoderFactory.java

+13-9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
2020
import org.springframework.security.oauth2.core.OAuth2Error;
2121
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
22+
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
2223
import org.springframework.security.oauth2.jwt.Jwt;
2324
import org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder;
2425
import org.springframework.security.oauth2.jwt.ReactiveJwtDecoder;
@@ -31,14 +32,16 @@
3132
import java.util.function.Function;
3233

3334
/**
34-
* Provides a default or custom reactive implementation for {@link OAuth2TokenValidator}
35+
* A {@link ReactiveJwtDecoderFactory factory} that provides a {@link ReactiveJwtDecoder}
36+
* used for {@link OidcIdToken} signature verification.
37+
* The provided {@link ReactiveJwtDecoder} is associated to a specific {@link ClientRegistration}.
3538
*
3639
* @author Joe Grandja
3740
* @author Rafael Dominguez
3841
* @since 5.2
39-
*
40-
* @see OAuth2TokenValidator
41-
* @see Jwt
42+
* @see ReactiveJwtDecoderFactory
43+
* @see ClientRegistration
44+
* @see OidcIdToken
4245
*/
4346
public final class ReactiveOidcIdTokenDecoderFactory implements ReactiveJwtDecoderFactory<ClientRegistration> {
4447
private static final String MISSING_SIGNATURE_VERIFIER_ERROR_CODE = "missing_signature_verifier";
@@ -47,7 +50,7 @@ public final class ReactiveOidcIdTokenDecoderFactory implements ReactiveJwtDecod
4750

4851
@Override
4952
public ReactiveJwtDecoder createDecoder(ClientRegistration clientRegistration) {
50-
Assert.notNull(clientRegistration, "clientRegistration cannot be null.");
53+
Assert.notNull(clientRegistration, "clientRegistration cannot be null");
5154
return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), key -> {
5255
if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) {
5356
OAuth2Error oauth2Error = new OAuth2Error(
@@ -61,19 +64,20 @@ public ReactiveJwtDecoder createDecoder(ClientRegistration clientRegistration) {
6164
}
6265
NimbusReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder(
6366
clientRegistration.getProviderDetails().getJwkSetUri());
64-
OAuth2TokenValidator<Jwt> jwtValidator = jwtValidatorFactory.apply(clientRegistration);
67+
OAuth2TokenValidator<Jwt> jwtValidator = this.jwtValidatorFactory.apply(clientRegistration);
6568
jwtDecoder.setJwtValidator(jwtValidator);
6669
return jwtDecoder;
6770
});
6871
}
6972

7073
/**
71-
* Allows user customization for the {@link OAuth2TokenValidator}
74+
* Sets the factory that provides an {@link OAuth2TokenValidator}, which is used by the {@link ReactiveJwtDecoder}.
75+
* The default is {@link OidcIdTokenValidator}.
7276
*
73-
* @param jwtValidatorFactory
77+
* @param jwtValidatorFactory the factory that provides an {@link OAuth2TokenValidator}
7478
*/
7579
public final void setJwtValidatorFactory(Function<ClientRegistration, OAuth2TokenValidator<Jwt>> jwtValidatorFactory) {
76-
Assert.notNull(jwtValidatorFactory, "jwtValidatorFactory cannot be null.");
80+
Assert.notNull(jwtValidatorFactory, "jwtValidatorFactory cannot be null");
7781
this.jwtValidatorFactory = jwtValidatorFactory;
7882
}
7983
}

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenDecoderFactoryTests.java

+20-31
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,12 @@
2323
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
2424
import org.springframework.security.oauth2.jwt.Jwt;
2525

26-
import java.time.Duration;
2726
import java.util.function.Function;
2827

2928
import static org.assertj.core.api.Assertions.assertThat;
3029
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3130
import static org.mockito.ArgumentMatchers.any;
32-
import static org.mockito.Mockito.mock;
33-
import static org.mockito.Mockito.verify;
34-
import static org.mockito.Mockito.when;
31+
import static org.mockito.Mockito.*;
3532

3633
/**
3734
* @author Joe Grandja
@@ -45,55 +42,47 @@ public class OidcIdTokenDecoderFactoryTests {
4542

4643
private OidcIdTokenDecoderFactory idTokenDecoderFactory;
4744

45+
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> defaultJwtValidatorFactory = OidcIdTokenValidator::new;
46+
4847
@Before
4948
public void setUp() {
50-
idTokenDecoderFactory = new OidcIdTokenDecoderFactory();
49+
this.idTokenDecoderFactory = new OidcIdTokenDecoderFactory();
5150
}
5251

5352
@Test
54-
public void setJwtValidatorFactoryWhenNullThenThrowIllegalArgumentException(){
55-
assertThatThrownBy(()-> idTokenDecoderFactory.setJwtValidatorFactory(null))
53+
public void setJwtValidatorFactoryWhenNullThenThrowIllegalArgumentException() {
54+
assertThatThrownBy(() -> this.idTokenDecoderFactory.setJwtValidatorFactory(null))
5655
.isInstanceOf(IllegalArgumentException.class);
5756
}
5857

5958
@Test
60-
public void createDecoderWhenClientRegistrationNullThenThrowIllegalArgumentException(){
61-
assertThatThrownBy(() -> idTokenDecoderFactory.createDecoder(null))
59+
public void createDecoderWhenClientRegistrationNullThenThrowIllegalArgumentException() {
60+
assertThatThrownBy(() -> this.idTokenDecoderFactory.createDecoder(null))
6261
.isInstanceOf(IllegalArgumentException.class);
6362
}
6463

6564
@Test
66-
public void createDecoderWhenJwkSetUriEmptyThenThrowOAuth2AuthenticationException(){
67-
assertThatThrownBy(()-> idTokenDecoderFactory.createDecoder(registration.jwkSetUri(null).build()))
68-
.isInstanceOf(OAuth2AuthenticationException.class);
65+
public void createDecoderWhenJwkSetUriEmptyThenThrowOAuth2AuthenticationException() {
66+
assertThatThrownBy(() -> this.idTokenDecoderFactory.createDecoder(this.registration.jwkSetUri(null).build()))
67+
.isInstanceOf(OAuth2AuthenticationException.class);
6968
}
7069

7170
@Test
72-
public void createDecoderWhenClientRegistrationValidThenReturnDecoder(){
73-
assertThat(idTokenDecoderFactory.createDecoder(registration.build()))
71+
public void createDecoderWhenClientRegistrationValidThenReturnDecoder() {
72+
assertThat(this.idTokenDecoderFactory.createDecoder(this.registration.build()))
7473
.isNotNull();
7574
}
7675

7776
@Test
78-
public void createDecoderWhenCustomJwtValidatorFactorySetThenApplied(){
79-
Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customValidator = mock(Function.class);
80-
idTokenDecoderFactory.setJwtValidatorFactory(customValidator);
77+
public void createDecoderWhenCustomJwtValidatorFactorySetThenApplied() {
78+
Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customJwtValidatorFactory = mock(Function.class);
79+
this.idTokenDecoderFactory.setJwtValidatorFactory(customJwtValidatorFactory);
8180

82-
when(customValidator.apply(any(ClientRegistration.class)))
83-
.thenReturn(customJwtValidatorFactory.apply(registration.build()));
81+
when(customJwtValidatorFactory.apply(any(ClientRegistration.class)))
82+
.thenReturn(this.defaultJwtValidatorFactory.apply(this.registration.build()));
8483

85-
idTokenDecoderFactory.createDecoder(registration.build());
84+
this.idTokenDecoderFactory.createDecoder(this.registration.build());
8685

87-
verify(customValidator).apply(any(ClientRegistration.class));
86+
verify(customJwtValidatorFactory).apply(any(ClientRegistration.class));
8887
}
89-
90-
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customJwtValidatorFactory = (c) -> {
91-
OidcIdTokenValidator idTokenValidator = new OidcIdTokenValidator(c);
92-
if (c.getRegistrationId().equals("registration-id1")) {
93-
idTokenValidator.setClockSkew(Duration.ofSeconds(30));
94-
} else if (c.getRegistrationId().equals("registration-id2")) {
95-
idTokenValidator.setClockSkew(Duration.ofSeconds(70));
96-
}
97-
return idTokenValidator;
98-
};
9988
}

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/authentication/ReactiveOidcIdTokenDecoderFactoryTests.java

+19-30
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,12 @@
2323
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
2424
import org.springframework.security.oauth2.jwt.Jwt;
2525

26-
import java.time.Duration;
2726
import java.util.function.Function;
2827

2928
import static org.assertj.core.api.Assertions.assertThat;
3029
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3130
import static org.mockito.ArgumentMatchers.any;
32-
import static org.mockito.Mockito.mock;
33-
import static org.mockito.Mockito.verify;
34-
import static org.mockito.Mockito.when;
31+
import static org.mockito.Mockito.*;
3532

3633
/**
3734
* @author Joe Grandja
@@ -45,55 +42,47 @@ public class ReactiveOidcIdTokenDecoderFactoryTests {
4542

4643
private ReactiveOidcIdTokenDecoderFactory idTokenDecoderFactory;
4744

45+
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> defaultJwtValidatorFactory = OidcIdTokenValidator::new;
46+
4847
@Before
4948
public void setUp() {
50-
idTokenDecoderFactory = new ReactiveOidcIdTokenDecoderFactory();
49+
this.idTokenDecoderFactory = new ReactiveOidcIdTokenDecoderFactory();
5150
}
5251

5352
@Test
54-
public void setJwtValidatorFactoryWhenNullThenThrowIllegalArgumentException(){
55-
assertThatThrownBy(()-> idTokenDecoderFactory.setJwtValidatorFactory(null))
53+
public void setJwtValidatorFactoryWhenNullThenThrowIllegalArgumentException() {
54+
assertThatThrownBy(() -> this.idTokenDecoderFactory.setJwtValidatorFactory(null))
5655
.isInstanceOf(IllegalArgumentException.class);
5756
}
5857

5958
@Test
60-
public void createDecoderWhenClientRegistrationNullThenThrowIllegalArgumentException(){
61-
assertThatThrownBy(() -> idTokenDecoderFactory.createDecoder(null))
59+
public void createDecoderWhenClientRegistrationNullThenThrowIllegalArgumentException() {
60+
assertThatThrownBy(() -> this.idTokenDecoderFactory.createDecoder(null))
6261
.isInstanceOf(IllegalArgumentException.class);
6362
}
6463

6564
@Test
66-
public void createDecoderWhenJwkSetUriEmptyThenThrowOAuth2AuthenticationException(){
67-
assertThatThrownBy(()-> idTokenDecoderFactory.createDecoder(registration.jwkSetUri(null).build()))
65+
public void createDecoderWhenJwkSetUriEmptyThenThrowOAuth2AuthenticationException() {
66+
assertThatThrownBy(() -> this.idTokenDecoderFactory.createDecoder(this.registration.jwkSetUri(null).build()))
6867
.isInstanceOf(OAuth2AuthenticationException.class);
6968
}
7069

7170
@Test
72-
public void createDecoderWhenClientRegistrationValidThenReturnDecoder(){
73-
assertThat(idTokenDecoderFactory.createDecoder(registration.build()))
71+
public void createDecoderWhenClientRegistrationValidThenReturnDecoder() {
72+
assertThat(this.idTokenDecoderFactory.createDecoder(this.registration.build()))
7473
.isNotNull();
7574
}
7675

7776
@Test
78-
public void createDecoderWhenCustomJwtValidatorFactorySetThenApplied(){
79-
Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customValidator = mock(Function.class);
80-
idTokenDecoderFactory.setJwtValidatorFactory(customValidator);
77+
public void createDecoderWhenCustomJwtValidatorFactorySetThenApplied() {
78+
Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customJwtValidatorFactory = mock(Function.class);
79+
this.idTokenDecoderFactory.setJwtValidatorFactory(customJwtValidatorFactory);
8180

82-
when(customValidator.apply(any(ClientRegistration.class)))
83-
.thenReturn(customJwtValidatorFactory.apply(registration.build()));
81+
when(customJwtValidatorFactory.apply(any(ClientRegistration.class)))
82+
.thenReturn(this.defaultJwtValidatorFactory.apply(this.registration.build()));
8483

85-
idTokenDecoderFactory.createDecoder(registration.build());
84+
this.idTokenDecoderFactory.createDecoder(this.registration.build());
8685

87-
verify(customValidator).apply(any(ClientRegistration.class));
86+
verify(customJwtValidatorFactory).apply(any(ClientRegistration.class));
8887
}
89-
90-
private Function<ClientRegistration, OAuth2TokenValidator<Jwt>> customJwtValidatorFactory = (c) -> {
91-
OidcIdTokenValidator idTokenValidator = new OidcIdTokenValidator(c);
92-
if (c.getRegistrationId().equals("registration-id1")) {
93-
idTokenValidator.setClockSkew(Duration.ofSeconds(30));
94-
} else if (c.getRegistrationId().equals("registration-id2")) {
95-
idTokenValidator.setClockSkew(Duration.ofSeconds(70));
96-
}
97-
return idTokenValidator;
98-
};
9988
}

0 commit comments

Comments
 (0)