Skip to content

Commit 4d1e2d9

Browse files
committed
Polish gh-1723
1 parent acd4fd0 commit 4d1e2d9

File tree

5 files changed

+59
-11
lines changed

5 files changed

+59
-11
lines changed

docs/modules/ROOT/pages/protocol-endpoints.adoc

+48-1
Original file line numberDiff line numberDiff line change
@@ -557,15 +557,62 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
557557
[[oidc-logout-endpoint-customizing-logout-request-validation]]
558558
=== Customizing Logout Request Validation
559559

560-
`OidcLogoutAuthenticationValidator` is the default validator used for validating specific OpenID Connect Logout request parameters used in the RP-Initiated Logout flow.
560+
`OidcLogoutAuthenticationValidator` is the default validator used for validating specific OpenID Connect RP-Initiated Logout Request parameters.
561561
The default implementation validates the `post_logout_redirect_uri` parameter.
562562
If validation fails, an `OAuth2AuthenticationException` is thrown.
563563

564564
`OidcLogoutAuthenticationProvider` provides the ability to override the default logout request validation by supplying a custom authentication validator of type `Consumer<OidcLogoutAuthenticationContext>` to `setAuthenticationValidator()`.
565565

566+
[TIP]
567+
`OidcLogoutAuthenticationContext` holds the `OidcLogoutAuthenticationToken`, which contains the logout request parameters.
568+
566569
[IMPORTANT]
567570
If validation fails, the authentication validator *MUST* throw `OAuth2AuthenticationException`.
568571

572+
The following example shows how to configure `OidcLogoutAuthenticationProvider` with a custom authentication validator:
573+
574+
[source,java]
575+
----
576+
@Bean
577+
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
578+
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
579+
new OAuth2AuthorizationServerConfigurer();
580+
http.apply(authorizationServerConfigurer);
581+
582+
authorizationServerConfigurer
583+
.oidc(oidc ->
584+
oidc
585+
.logoutEndpoint(logoutEndpoint ->
586+
logoutEndpoint.authenticationProviders(configureAuthenticationValidator()))
587+
);
588+
589+
return http.build();
590+
}
591+
592+
private Consumer<List<AuthenticationProvider>> configureAuthenticationValidator() {
593+
return (authenticationProviders) ->
594+
authenticationProviders.forEach((authenticationProvider) -> {
595+
if (authenticationProvider instanceof OidcLogoutAuthenticationProvider oidcLogoutAuthenticationProvider) {
596+
Consumer<OidcLogoutAuthenticationContext> authenticationValidator = new CustomPostLogoutRedirectUriValidator();
597+
oidcLogoutAuthenticationProvider.setAuthenticationValidator(authenticationValidator);
598+
}
599+
});
600+
}
601+
602+
static class CustomPostLogoutRedirectUriValidator implements Consumer<OidcLogoutAuthenticationContext> {
603+
604+
@Override
605+
public void accept(OidcLogoutAuthenticationContext authenticationContext) {
606+
OidcLogoutAuthenticationToken oidcLogoutAuthentication =
607+
authenticationContext.getAuthentication();
608+
RegisteredClient registeredClient = authenticationContext.getRegisteredClient();
609+
610+
// TODO
611+
612+
}
613+
}
614+
----
615+
569616
[[oidc-user-info-endpoint]]
570617
== OpenID Connect 1.0 UserInfo Endpoint
571618

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationContext.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
*/
1616
package org.springframework.security.oauth2.server.authorization.oidc.authentication;
1717

18+
import java.util.Collections;
19+
import java.util.HashMap;
1820
import java.util.Map;
1921
import java.util.function.Consumer;
2022

2123
import org.springframework.lang.Nullable;
22-
import org.springframework.security.core.Authentication;
2324
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthenticationContext;
2425
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
2526
import org.springframework.util.Assert;
@@ -40,7 +41,7 @@ public final class OidcLogoutAuthenticationContext implements OAuth2Authenticati
4041
private final Map<Object, Object> context;
4142

4243
private OidcLogoutAuthenticationContext(Map<Object, Object> context) {
43-
this.context = context;
44+
this.context = Collections.unmodifiableMap(new HashMap<>(context));
4445
}
4546

4647
@SuppressWarnings("unchecked")
@@ -79,7 +80,7 @@ public static Builder with(OidcLogoutAuthenticationToken authentication) {
7980
*/
8081
public static final class Builder extends AbstractBuilder<OidcLogoutAuthenticationContext, Builder> {
8182

82-
private Builder(Authentication authentication) {
83+
private Builder(OidcLogoutAuthenticationToken authentication) {
8384
super(authentication);
8485
}
8586

@@ -98,6 +99,7 @@ public Builder registeredClient(RegisteredClient registeredClient) {
9899
*/
99100
@Override
100101
public OidcLogoutAuthenticationContext build() {
102+
Assert.notNull(get(RegisteredClient.class), "registeredClient cannot be null");
101103
return new OidcLogoutAuthenticationContext(getContext());
102104
}
103105

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProvider.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public boolean supports(Class<?> authentication) {
188188
/**
189189
* Sets the {@code Consumer} providing access to the
190190
* {@link OidcLogoutAuthenticationContext} and is responsible for validating specific
191-
* Open ID Connect RP-Initiated Logout Request parameters associated in the
191+
* OpenID Connect RP-Initiated Logout Request parameters associated in the
192192
* {@link OidcLogoutAuthenticationToken}. The default authentication validator is
193193
* {@link OidcLogoutAuthenticationValidator}.
194194
*
@@ -197,7 +197,7 @@ public boolean supports(Class<?> authentication) {
197197
* {@link OAuth2AuthenticationException} if validation fails.
198198
* @param authenticationValidator the {@code Consumer} providing access to the
199199
* {@link OidcLogoutAuthenticationContext} and is responsible for validating specific
200-
* Open ID Connect RP-Initiated Logout Request parameters
200+
* OpenID Connect RP-Initiated Logout Request parameters
201201
* @since 1.4
202202
*/
203203
public void setAuthenticationValidator(Consumer<OidcLogoutAuthenticationContext> authenticationValidator) {

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationValidator.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
2121
import org.springframework.security.oauth2.core.OAuth2Error;
2222
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
23-
import org.springframework.security.oauth2.core.oidc.OidcIdToken;
2423
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
2524
import org.springframework.util.StringUtils;
2625

@@ -29,10 +28,10 @@
2928
* containing an {@link OidcLogoutAuthenticationToken} and is the default
3029
* {@link OidcLogoutAuthenticationProvider#setAuthenticationValidator(Consumer)
3130
* authentication validator} used for validating specific OpenID Connect RP-Initiated
32-
* Logout parameters used in the Authorization Code Grant.
31+
* Logout Request parameters.
3332
*
3433
* <p>
35-
* The default implementation first validates {@link OidcIdToken#getAudience()}, and then
34+
* The default implementation validates
3635
* {@link OidcLogoutAuthenticationToken#getPostLogoutRedirectUri()}. If validation fails,
3736
* an {@link OAuth2AuthenticationException} is thrown.
3837
*

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/oidc/authentication/OidcLogoutAuthenticationProviderTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ public void authenticateWhenInvalidPostLogoutRedirectUriThenThrowOAuth2Authentic
317317
}
318318

319319
@Test
320-
void setAuthenticationValidatorWhenNullThenThrowIllegalArgumentException() {
320+
public void setAuthenticationValidatorWhenNullThenThrowIllegalArgumentException() {
321321
assertThatThrownBy(() -> this.authenticationProvider.setAuthenticationValidator(null))
322322
.isInstanceOf(IllegalArgumentException.class)
323323
.hasMessage("authenticationValidator cannot be null");
@@ -342,7 +342,7 @@ public void authenticateWhenCustomAuthenticationValidatorThenUsed() throws NoSuc
342342
this.authenticationProvider.setAuthenticationValidator(authenticationValidator);
343343

344344
authenticateValidIdToken(principal, registeredClient, sessionId, idToken);
345-
verify(authenticationValidator).accept(any());
345+
verify(authenticationValidator).accept(any(OidcLogoutAuthenticationContext.class));
346346
}
347347

348348
@Test

0 commit comments

Comments
 (0)