Describe the bug When OidcClientInitiatedServerLogoutSuccessHandler is configured, the redirect logout is not initiated in the client. I think something changed in Spring Security. This was working as expected up to version2.3.10.RELEASE of Spring Boot, but after 2.4.0 stopped working.

This behaviour is visible in these two places: - authentication.getPrincipal() does not produce an instance of OidcUser in here - Adding the argument @AuthenticationPrincipal OidcUser oidcUser to an endpoint always gives null.

To Reproduce 1. Login in the App using the Identity Provider. 2. Observe the value of oidcUser when calling the endpoint GET / 3. Perform the logout action

Expected behavior Perform the logout from the Identity Provider. The URL used for this is defined by end_session_endpoint and we should see a redirect with it in the network log (browser inspector).

Sample Used dependencies: - org.springframework.boot:spring-boot-starter-webflux:2.4.5 - org.springframework.boot:spring-boot-starter-oauth2-client:2.4.5

application.yml:

spring:
  security:
    oauth2:
      client:
        registration:
          keycloak:
            provider: keycloak
            client-id: example
            client-secret: secret
        provider:
          keycloak:
            issuer-uri: http://localhost-keycloak:8080/auth/realms/example

Sample application:

package sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.oidc.web.server.logout.OidcClientInitiatedServerLogoutSuccessHandler;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@SpringBootApplication
@RestController
@EnableWebFluxSecurity
public class ReactiveOAuth2LoginApplication {
    @Autowired
    private ReactiveClientRegistrationRepository clientRegistrationRepository;

    public static void main(String[] args) {
        SpringApplication.run(ReactiveOAuth2LoginApplication.class, args);
    }

    @GetMapping("/")
    public Mono<String> index(@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authorizedClient,
                  @AuthenticationPrincipal OidcUser oidcUser) {
        return Mono.just(authorizedClient.getAccessToken().getTokenValue());
    }

    @Bean
    SecurityWebFilterChain configure(ServerHttpSecurity http) {
        http
            .authorizeExchange()
                .anyExchange()
                .authenticated()
                .and()
            .oauth2Login()
                .and()
            .logout(logout -> logout
                    .logoutSuccessHandler(oidcLogoutSuccessHandler()));

        return http.build();
    }
    private ServerLogoutSuccessHandler oidcLogoutSuccessHandler() {
        OidcClientInitiatedServerLogoutSuccessHandler oidcLogoutSuccessHandler =
                new OidcClientInitiatedServerLogoutSuccessHandler(this.clientRegistrationRepository);

        // Sets the location that the End-User's User Agent will be redirected to
        // after the logout has been performed at the Provider
        oidcLogoutSuccessHandler.setPostLogoutRedirectUri("{baseUrl}");

        return oidcLogoutSuccessHandler;
    }
}

Comment From: jzheaux

I wonder if this is related to https://github.com/spring-projects/spring-security/commit/0486d5add983dd09295fffeee13015cdd74bf322.

@rigon, if you specify the list of scopes that you require in the spring.security.oauth2.client.registration.keycloak.scope property, does that repair the behavior?

It would need to at least include openid:

```yaml spring: security: oauth2: client: registration: keycloak: scope: openid ````

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: rigon

@jzheaux That is actually true. Specifying the scope openid solves the problem, the application works as intended. Thanks a lot for the tip.

I was migrating my Spring Boot application from 2.3 to 2.4. The confusion with this had to do with the fact that I was relying on default scopes without realizing it and wasn't clear in the documentation. Closing this issue.

Comment From: jzheaux

Glad that worked, @rigon. Is there someplace in the documentation that you feel should be changed? If so, would you be able to submit a PR?

Comment From: straurob

Today I ran into the same issue with spring-boot-starter-oauth2-client:2.6.3. After having added scope: openid to my application.yml, the end_session_endpoint was correctly resolved from Keycloak configuration URL.

However, I quite don't understand the relation between the scope parameter and this issue. Has there been an update of the documentation which I might be missing? @jzheaux

Having read #5494 and especially this comment my understanding is this: - The scope parameter is OPTIONAL with regards to the OAuth2 spec. This is why Spring Security allows it to be empty/null and doesn't complain. - However, the oauth2Login() and logout() features, e.g. OidcClientInitiatedServerLogoutSuccessHandler, require the scope parameter to be at least openid.

Is my understanding correct?

Comment From: jzheaux

Yes, @straurob, you've got it right.