Polish gh-946

This commit is contained in:
Joe Grandja
2022-10-28 15:37:41 -04:00
parent efbfdc234c
commit bfd7a09c3b
5 changed files with 130 additions and 120 deletions

View File

@@ -353,8 +353,10 @@ The guide xref:guides/how-to-userinfo.adoc#how-to-userinfo[How-to: Customize the
[[oidc-client-registration-endpoint]]
== OpenID Connect 1.0 Client Registration Endpoint
`OidcClientRegistrationEndpointConfigurer` configures the https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OpenID Connect 1.0 Client Registration endpoint].
The following example shows how to enable (disabled by default) the OpenID Connect 1.0 Client Registration endpoint:
`OidcClientRegistrationEndpointConfigurer` provides the ability to customize the https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OpenID Connect 1.0 Client Registration endpoint].
It defines extension points that let you customize the pre-processing, main processing, and post-processing logic for https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration requests] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read requests].
`OidcClientRegistrationEndpointConfigurer` provides the following configuration options:
[source,java]
----
@@ -375,18 +377,18 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
.authenticationProviders(authenticationProvidersConsumer) <4>
.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
)
);
return http.build();
}
----
<1> `clientRegistrationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract a https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration Request] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read Request] from `HttpServletRequest` to an instance of `OidcClientRegistrationAuthenticationToken`.
<1> `clientRegistrationRequestConverter()`: Adds an `AuthenticationConverter` (_pre-processor_) used when attempting to extract a https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationRequest[Client Registration request] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadRequest[Client Read request] from `HttpServletRequest` to an instance of `OidcClientRegistrationAuthenticationToken`.
<2> `clientRegistrationRequestConverters()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationConverter``'s allowing the ability to add, remove, or customize a specific `AuthenticationConverter`.
<3> `authenticationProvider()`: Adds an `AuthenticationProvider` (_main processor_) used for authenticating the `OidcClientRegistrationAuthenticationToken`.
<4> `authenticationProviders()`: Sets the `Consumer` providing access to the `List` of default and (optionally) added ``AuthenticationProvider``'s allowing the ability to add, remove, or customize a specific `AuthenticationProvider`.
<5> `clientRegistrationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[Client Registration Response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse[Client Read Response].
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError[Client Registration Error Response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadError[Client Read Error Response].
<5> `clientRegistrationResponseHandler()`: The `AuthenticationSuccessHandler` (_post-processor_) used for handling an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationResponse[Client Registration response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadResponse[Client Read response].
<6> `errorResponseHandler()`: The `AuthenticationFailureHandler` (_post-processor_) used for handling an `OAuth2AuthenticationException` and returning the https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError[Client Registration Error response] or https://openid.net/specs/openid-connect-registration-1_0.html#ReadError[Client Read Error response].
[NOTE]
The OpenID Connect 1.0 Client Registration endpoint is disabled by default because many deployments do not require dynamic client registration.
@@ -401,7 +403,7 @@ The OpenID Connect 1.0 Client Registration endpoint is disabled by default becau
* `*AuthenticationConverter*` -- An `OidcClientRegistrationAuthenticationConverter`.
* `*AuthenticationManager*` -- An `AuthenticationManager` composed of `OidcClientRegistrationAuthenticationProvider` and `OidcClientConfigurationAuthenticationProvider`.
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returns the Client Registration or Client Read response.
* `*AuthenticationSuccessHandler*` -- An internal implementation that handles an "`authenticated`" `OidcClientRegistrationAuthenticationToken` and returns the `OidcClientRegistration` response.
* `*AuthenticationFailureHandler*` -- An internal implementation that uses the `OAuth2Error` associated with the `OAuth2AuthenticationException` and returns the `OAuth2Error` response.
The OpenID Connect 1.0 Client Registration endpoint is an https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OAuth2 protected resource], which *REQUIRES* an access token to be sent as a bearer token in the Client Registration (or Client Read) request.

View File

@@ -28,7 +28,7 @@ import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.oidc.OidcUserInfo;
import org.springframework.security.oauth2.server.authorization.oidc.OidcClientRegistration;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientConfigurationAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationToken;
@@ -46,7 +46,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
/**
* Configurer for OpenID Connect Dynamic Client Registration 1.0 Endpoint.
* Configurer for OpenID Connect 1.0 Dynamic Client Registration Endpoint.
*
* @author Joe Grandja
* @author Daniel Garnier-Moiroux
@@ -57,7 +57,7 @@ import org.springframework.util.Assert;
public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAuth2Configurer {
private RequestMatcher requestMatcher;
private final List<AuthenticationConverter> clientRegistrationRequestConverters = new ArrayList<>();
private Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer = (authenticationConverters) -> {};
private Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer = (clientRegistrationRequestConverters) -> {};
private final List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
private Consumer<List<AuthenticationProvider>> authenticationProvidersConsumer = (authenticationProviders) -> {};
private AuthenticationSuccessHandler clientRegistrationResponseHandler;
@@ -71,12 +71,10 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
}
/**
* Sets the {@link AuthenticationConverter} used when attempting to extract the OIDC Client Registration Request
* from {@link HttpServletRequest} to an instance of {@link OidcClientRegistrationAuthenticationToken} used for
* creating the Client Registration or returning the Client Read Response.
* Adds an {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
* to an instance of {@link OidcClientRegistrationAuthenticationToken} used for authenticating the request.
*
* @param clientRegistrationRequestConverter the {@link AuthenticationConverter} used when attempting to extract an
* OIDC Client Registration Request from {@link HttpServletRequest}
* @param clientRegistrationRequestConverter an {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
* @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
* @since 0.4.0
*/
@@ -96,16 +94,17 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
* @return the {@link OidcUserInfoEndpointConfigurer} for further configuration
* @since 0.4.0
*/
public OidcClientRegistrationEndpointConfigurer clientRegistrationRequestConverters(Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer) {
public OidcClientRegistrationEndpointConfigurer clientRegistrationRequestConverters(
Consumer<List<AuthenticationConverter>> clientRegistrationRequestConvertersConsumer) {
Assert.notNull(clientRegistrationRequestConvertersConsumer, "clientRegistrationRequestConvertersConsumer cannot be null");
this.clientRegistrationRequestConvertersConsumer = clientRegistrationRequestConvertersConsumer;
return this;
}
/**
* Adds an {@link AuthenticationProvider} used for authenticating a type of {@link OidcClientRegistrationAuthenticationToken}.
* Adds an {@link AuthenticationProvider} used for authenticating an {@link OidcClientRegistrationAuthenticationToken}.
*
* @param authenticationProvider a {@link AuthenticationProvider} used for authenticating a type of {@link OidcClientRegistrationAuthenticationToken}
* @param authenticationProvider an {@link AuthenticationProvider} used for authenticating an {@link OidcClientRegistrationAuthenticationToken}
* @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
* @since 0.4.0
*/
@@ -132,8 +131,8 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
}
/**
* Sets the {@link AuthenticationSuccessHandler} used for handling an {@link OidcClientRegistrationAuthenticationToken} and
* returning the {@link OidcUserInfo User Info Response}.
* Sets the {@link AuthenticationSuccessHandler} used for handling an {@link OidcClientRegistrationAuthenticationToken}
* and returning the {@link OidcClientRegistration Client Registration Response}.
*
* @param clientRegistrationResponseHandler the {@link AuthenticationSuccessHandler} used for handling an {@link OidcClientRegistrationAuthenticationToken}
* @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
@@ -145,8 +144,8 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
}
/**
* Sets the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException} and
* returning the {@link OAuth2Error Error Response}.
* Sets the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
* and returning the {@link OAuth2Error Error Response}.
*
* @param errorResponseHandler the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
* @return the {@link OidcClientRegistrationEndpointConfigurer} for further configuration
@@ -160,18 +159,17 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
@Override
void init(HttpSecurity httpSecurity) {
AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils.getAuthorizationServerSettings(httpSecurity);
String clientRegistrationEndpointUri = authorizationServerSettings.getOidcClientRegistrationEndpoint();
this.requestMatcher = new OrRequestMatcher(
new AntPathRequestMatcher(authorizationServerSettings.getOidcClientRegistrationEndpoint(), HttpMethod.POST.name()),
new AntPathRequestMatcher(authorizationServerSettings.getOidcClientRegistrationEndpoint(), HttpMethod.GET.name())
new AntPathRequestMatcher(clientRegistrationEndpointUri, HttpMethod.POST.name()),
new AntPathRequestMatcher(clientRegistrationEndpointUri, HttpMethod.GET.name())
);
List<AuthenticationProvider> authenticationProviders = createDefaultAuthenticationProviders(httpSecurity);
if (!this.authenticationProviders.isEmpty()) {
authenticationProviders.addAll(0, this.authenticationProviders);
}
this.authenticationProvidersConsumer.accept(authenticationProviders);
authenticationProviders.forEach(authenticationProvider ->
httpSecurity.authenticationProvider(postProcess(authenticationProvider)));
}
@@ -185,7 +183,6 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
new OidcClientRegistrationEndpointFilter(
authenticationManager,
authorizationServerSettings.getOidcClientRegistrationEndpoint());
List<AuthenticationConverter> authenticationConverters = createDefaultAuthenticationConverters();
if (!this.clientRegistrationRequestConverters.isEmpty()) {
authenticationConverters.addAll(0, this.clientRegistrationRequestConverters);
@@ -193,7 +190,6 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
this.clientRegistrationRequestConvertersConsumer.accept(authenticationConverters);
oidcClientRegistrationEndpointFilter.setAuthenticationConverter(
new DelegatingAuthenticationConverter(authenticationConverters));
if (this.clientRegistrationResponseHandler != null) {
oidcClientRegistrationEndpointFilter
.setAuthenticationSuccessHandler(this.clientRegistrationResponseHandler);
@@ -209,6 +205,14 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
return this.requestMatcher;
}
private static List<AuthenticationConverter> createDefaultAuthenticationConverters() {
List<AuthenticationConverter> authenticationConverters = new ArrayList<>();
authenticationConverters.add(new OidcClientRegistrationAuthenticationConverter());
return authenticationConverters;
}
private static List<AuthenticationProvider> createDefaultAuthenticationProviders(HttpSecurity httpSecurity) {
List<AuthenticationProvider> authenticationProviders = new ArrayList<>();
@@ -224,13 +228,8 @@ public final class OidcClientRegistrationEndpointConfigurer extends AbstractOAut
OAuth2ConfigurerUtils.getRegisteredClientRepository(httpSecurity),
OAuth2ConfigurerUtils.getAuthorizationService(httpSecurity));
authenticationProviders.add(oidcClientConfigurationAuthenticationProvider);
return authenticationProviders;
}
private static List<AuthenticationConverter> createDefaultAuthenticationConverters() {
List<AuthenticationConverter> authenticationConverters = new ArrayList<>();
authenticationConverters.add(new OidcClientRegistrationAuthenticationConverter());
return authenticationConverters;
}
}

View File

@@ -74,11 +74,11 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
private final AuthenticationManager authenticationManager;
private final RequestMatcher clientRegistrationEndpointMatcher;
private AuthenticationConverter authenticationConverter = new OidcClientRegistrationAuthenticationConverter();
private final HttpMessageConverter<OidcClientRegistration> clientRegistrationHttpMessageConverter =
new OidcClientRegistrationHttpMessageConverter();
private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
new OAuth2ErrorHttpMessageConverter();
private AuthenticationConverter authenticationConverter = new OidcClientRegistrationAuthenticationConverter();
private AuthenticationSuccessHandler authenticationSuccessHandler = this::sendClientRegistrationResponse;
private AuthenticationFailureHandler authenticationFailureHandler = this::sendErrorResponse;
@@ -130,11 +130,10 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
}
try {
OidcClientRegistrationAuthenticationToken clientRegistrationAuthentication =
(OidcClientRegistrationAuthenticationToken) this.authenticationConverter.convert(request);
Authentication clientRegistrationAuthentication = this.authenticationConverter.convert(request);
OidcClientRegistrationAuthenticationToken clientRegistrationAuthenticationResult =
(OidcClientRegistrationAuthenticationToken) this.authenticationManager.authenticate(clientRegistrationAuthentication);
Authentication clientRegistrationAuthenticationResult =
this.authenticationManager.authenticate(clientRegistrationAuthentication);
this.authenticationSuccessHandler.onAuthenticationSuccess(request, response, clientRegistrationAuthenticationResult);
} catch (OAuth2AuthenticationException ex) {
@@ -142,7 +141,7 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
} catch (Exception ex) {
OAuth2Error error = new OAuth2Error(
OAuth2ErrorCodes.INVALID_REQUEST,
"OpenID Client Registration Error: " + ex.getMessage(),
"OpenID Connect 1.0 Client Registration Error: " + ex.getMessage(),
"https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError");
this.authenticationFailureHandler.onAuthenticationFailure(request, response,
new OAuth2AuthenticationException(error));
@@ -152,12 +151,10 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
}
/**
* Sets the {@link AuthenticationConverter} used when attempting to extract the OIDC Client Registration Request
* from {@link HttpServletRequest} to an instance of {@link OidcClientRegistrationAuthenticationToken} used for
* creating the Client Registration or returning the Client Read Response.
* Sets the {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
* to an instance of {@link OidcClientRegistrationAuthenticationToken} used for authenticating the request.
*
* @param authenticationConverter the {@link AuthenticationConverter} used when attempting to extract an
* OIDC Client Registration Request from {@link HttpServletRequest}
* @param authenticationConverter an {@link AuthenticationConverter} used when attempting to extract a Client Registration Request from {@link HttpServletRequest}
* @since 0.4.0
*/
public void setAuthenticationConverter(AuthenticationConverter authenticationConverter) {
@@ -178,11 +175,10 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
}
/**
* Sets the {@link AuthenticationFailureHandler} used for handling an
* {@link OAuth2AuthenticationException} and returning the {@link OAuth2Error Error
* Response}.
* @param authenticationFailureHandler the {@link AuthenticationFailureHandler} used
* for handling an {@link OAuth2AuthenticationException}
* Sets the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
* and returning the {@link OAuth2Error Error Response}.
*
* @param authenticationFailureHandler the {@link AuthenticationFailureHandler} used for handling an {@link OAuth2AuthenticationException}
* @since 0.4.0
*/
public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
@@ -197,8 +193,7 @@ public final class OidcClientRegistrationEndpointFilter extends OncePerRequestFi
ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
if (HttpMethod.POST.name().equals(request.getMethod())) {
httpResponse.setStatusCode(HttpStatus.CREATED);
}
else {
} else {
httpResponse.setStatusCode(HttpStatus.OK);
}
this.clientRegistrationHttpMessageConverter.write(clientRegistration, null, httpResponse);

View File

@@ -88,6 +88,7 @@ import org.springframework.security.oauth2.server.authorization.oidc.authenticat
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.oidc.authentication.OidcClientRegistrationAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.oidc.http.converter.OidcClientRegistrationHttpMessageConverter;
import org.springframework.security.oauth2.server.authorization.oidc.web.authentication.OidcClientRegistrationAuthenticationConverter;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
import org.springframework.security.oauth2.server.authorization.test.SpringTestRule;
@@ -308,7 +309,7 @@ public class OidcClientRegistrationTests {
}
@Test
public void requestWhenUserInfoEndpointCustomizedThenUsed() throws Exception {
public void requestWhenClientRegistrationEndpointCustomizedThenUsed() throws Exception {
this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
// @formatter:off
@@ -333,15 +334,17 @@ public class OidcClientRegistrationTests {
registerClient(clientRegistration);
verify(authenticationConverter).convert(any());
ArgumentCaptor<List<AuthenticationConverter>> authenticationConvertersCaptor = ArgumentCaptor
.forClass(List.class);
ArgumentCaptor<List<AuthenticationConverter>> authenticationConvertersCaptor =
ArgumentCaptor.forClass(List.class);
verify(authenticationConvertersConsumer).accept(authenticationConvertersCaptor.capture());
List<AuthenticationConverter> authenticationConverters = authenticationConvertersCaptor.getValue();
assertThat(authenticationConverters).hasSize(2).contains(authenticationConverter);
assertThat(authenticationConverters).hasSize(2)
.allMatch(converter -> converter == authenticationConverter
|| converter instanceof OidcClientRegistrationAuthenticationConverter);
verify(authenticationProvider).authenticate(any());
ArgumentCaptor<List<AuthenticationProvider>> authenticationProvidersCaptor = ArgumentCaptor
.forClass(List.class);
ArgumentCaptor<List<AuthenticationProvider>> authenticationProvidersCaptor =
ArgumentCaptor.forClass(List.class);
verify(authenticationProvidersConsumer).accept(authenticationProvidersCaptor.capture());
List<AuthenticationProvider> authenticationProviders = authenticationProvidersCaptor.getValue();
assertThat(authenticationProviders).hasSize(3)
@@ -354,7 +357,7 @@ public class OidcClientRegistrationTests {
}
@Test
public void requestWhenUserInfoEndpointCustomizedAndErrorThenUsed() throws Exception {
public void requestWhenClientRegistrationEndpointCustomizedWithAuthenticationFailureHandlerThenUsed() throws Exception {
this.spring.register(CustomClientRegistrationConfiguration.class).autowire();
when(authenticationProvider.authenticate(any())).thenThrow(new OAuth2AuthenticationException("error"));
@@ -461,27 +464,38 @@ public class OidcClientRegistrationTests {
@EnableWebSecurity
static class CustomClientRegistrationConfiguration extends AuthorizationServerConfiguration {
// @formatter:off
@Bean
@Override
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer.oidc(oidc -> oidc.clientRegistrationEndpoint(
clientRegistration -> clientRegistration.clientRegistrationRequestConverter(authenticationConverter)
.clientRegistrationRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.clientRegistrationResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler)));
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.oidc(oidc ->
oidc
.clientRegistrationEndpoint(clientRegistration ->
clientRegistration
.clientRegistrationRequestConverter(authenticationConverter)
.clientRegistrationRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.clientRegistrationResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler)
)
);
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
http.requestMatcher(endpointsMatcher)
.authorizeRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated())
http
.requestMatcher(endpointsMatcher)
.authorizeRequests(authorizeRequests ->
authorizeRequests.anyRequest().authenticated()
)
.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt).apply(authorizationServerConfigurer);
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.apply(authorizationServerConfigurer);
return http.build();
}
// @formatter:on
}
@EnableWebSecurity

View File

@@ -371,27 +371,6 @@ public class OidcClientRegistrationEndpointFilterTests {
OAuth2ErrorCodes.INVALID_CLIENT, HttpStatus.UNAUTHORIZED);
}
@Test
public void doFilterWhenCustomAuthenticationFailureHandlerThenUsed() throws Exception {
AuthenticationFailureHandler authenticationFailureHandler = mock(AuthenticationFailureHandler.class);
this.filter.setAuthenticationFailureHandler(authenticationFailureHandler);
when(this.authenticationManager.authenticate(any()))
.thenThrow(new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN));
String requestUri = DEFAULT_OIDC_CLIENT_REGISTRATION_ENDPOINT_URI;
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
request.setServletPath(requestUri);
request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client1");
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain filterChain = mock(FilterChain.class);
this.filter.doFilter(request, response, filterChain);
verify(authenticationFailureHandler).onAuthenticationFailure(eq(request), eq(response),
any(OAuth2AuthenticationException.class));
}
private void doFilterWhenClientConfigurationRequestInvalidThenError(
String errorCode, HttpStatus status) throws Exception {
Jwt jwt = createJwt("client.read");
@@ -475,6 +454,24 @@ public class OidcClientRegistrationEndpointFilterTests {
.isEqualTo(expectedClientRegistrationResponse.getRegistrationClientUrl());
}
@Test
public void doFilterWhenCustomAuthenticationConverterThenUsed() throws ServletException, IOException {
AuthenticationConverter authenticationConverter = mock(AuthenticationConverter.class);
this.filter.setAuthenticationConverter(authenticationConverter);
String requestUri = DEFAULT_OIDC_CLIENT_REGISTRATION_ENDPOINT_URI;
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
request.setServletPath(requestUri);
request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client-id");
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain filterChain = mock(FilterChain.class);
this.filter.doFilter(request, response, filterChain);
verify(authenticationConverter).convert(request);
}
@Test
public void doFilterWhenCustomAuthenticationSuccessHandlerThenUsed() throws Exception {
OidcClientRegistration expectedClientRegistrationResponse = createClientRegistration();
@@ -504,43 +501,25 @@ public class OidcClientRegistrationEndpointFilterTests {
verify(successHandler).onAuthenticationSuccess(request, response, clientRegistrationAuthenticationResult);
}
private static OidcClientRegistration createClientRegistration() {
// @formatter:off
OidcClientRegistration expectedClientRegistrationResponse = OidcClientRegistration.builder()
.clientId("client-id")
.clientIdIssuedAt(Instant.now())
.clientSecret("client-secret")
.clientName("client-name")
.redirectUri("https://client.example.com")
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
.idTokenSignedResponseAlgorithm(SignatureAlgorithm.RS256.getName())
.scope("scope1")
.scope("scope2")
.registrationClientUrl("https://auth-server:9000/connect/register?client_id=client-id")
.build();
return expectedClientRegistrationResponse;
// @formatter:on
}
@Test
public void doFilterWhenCustomAuthenticationConverterThenUsed() throws ServletException, IOException {
AuthenticationConverter authenticationConverter = mock(AuthenticationConverter.class);
this.filter.setAuthenticationConverter(authenticationConverter);
public void doFilterWhenCustomAuthenticationFailureHandlerThenUsed() throws Exception {
AuthenticationFailureHandler authenticationFailureHandler = mock(AuthenticationFailureHandler.class);
this.filter.setAuthenticationFailureHandler(authenticationFailureHandler);
when(this.authenticationManager.authenticate(any()))
.thenThrow(new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_TOKEN));
String requestUri = DEFAULT_OIDC_CLIENT_REGISTRATION_ENDPOINT_URI;
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
request.setServletPath(requestUri);
request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client-id");
request.setParameter(OAuth2ParameterNames.CLIENT_ID, "client1");
MockHttpServletResponse response = new MockHttpServletResponse();
FilterChain filterChain = mock(FilterChain.class);
this.filter.doFilter(request, response, filterChain);
verify(authenticationConverter).convert(request);
verify(authenticationFailureHandler).onAuthenticationFailure(eq(request), eq(response),
any(OAuth2AuthenticationException.class));
}
private OAuth2Error readError(MockHttpServletResponse response) throws Exception {
@@ -562,6 +541,27 @@ public class OidcClientRegistrationEndpointFilterTests {
return this.clientRegistrationHttpMessageConverter.read(OidcClientRegistration.class, httpResponse);
}
private static OidcClientRegistration createClientRegistration() {
// @formatter:off
OidcClientRegistration clientRegistration = OidcClientRegistration.builder()
.clientId("client-id")
.clientIdIssuedAt(Instant.now())
.clientSecret("client-secret")
.clientName("client-name")
.redirectUri("https://client.example.com")
.grantType(AuthorizationGrantType.AUTHORIZATION_CODE.getValue())
.grantType(AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
.tokenEndpointAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC.getValue())
.responseType(OAuth2AuthorizationResponseType.CODE.getValue())
.idTokenSignedResponseAlgorithm(SignatureAlgorithm.RS256.getName())
.scope("scope1")
.scope("scope2")
.registrationClientUrl("https://auth-server:9000/connect/register?client_id=client-id")
.build();
return clientRegistration;
// @formatter:on
}
private static Jwt createJwt(String scope) {
// @formatter:off
JwsHeader jwsHeader = TestJwsHeaders.jwsHeader()