Summary

When configuring a WebFlux application as an OAuth2 Client using an authentication_code grant type and without implementing the OAuth2Login feature, the application redirects to the "/" path after authenticating in the Authentication Server instead of redirecting back to the original request

Actual Behavior

1-Calling an endpoint in an OAuth2 Client application (without using OAuth2 login) using Auth code Grant type 2- Authenticate in the Authorization Server 3- Get redirected to the /authorize/oauth2/code/[myclient] endpoint 4- Get redirected to the root ("/") URL

Expected Behavior

1-Calling an endpoint in an OAuth2 Client application (without using OAuth2 login) using Auth code Grant type 2- Authenticate in the Authorization Server 3- Get redirected to the /authorize/oauth2/code/[myclient] endpoint 4- Get redirected to the endpoint we called in the first place

Configuration

1- Set up an application with the following using the following ServerHttpSecurity configuration:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    http.authorizeExchange()
        .anyExchange()
        .permitAll()
        .and()
        .oauth2Client();
    return http.build();
}

2- A client registration:

spring.security.oauth2.client.registration.myclient.client-name=myclient
spring.security.oauth2.client.registration.myclient.client-id=myclient-client-id
spring.security.oauth2.client.registration.myclient.client-secret=myclient-secret
spring.security.oauth2.client.registration.myclient.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.myclient.redirect-uri-template=http://localhost:8080/authorize/oauth2/code/myclient

spring.security.oauth2.client.provider.myclient.token-uri=http://localhost:8085/oauth/token
spring.security.oauth2.client.provider.myclient.authorization-uri=http://localhost:8085/oauth/authorize

Note: In my case, I set up the Client registration using Spring Boot 2.x. The client is registered in a custom Authentication Provider that I configured using Spring Security Oauth, but the issue should be present for well-known providers as well.

3- Configure the WebClient:

@Bean
    WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations, ServerOAuth2AuthorizedClientRepository authorizedClients) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);
        oauth.setDefaultClientRegistrationId("myclient");
        return WebClient.builder()
            .filter(oauth)
            .build();
    }

4-And the endpoint that I'm using:

@RestController
public class ClientRestController {

    private static final String RESOURCE_URI = "http://localhost:8084/retrieve-resource";

    @Autowired
    WebClient webClient;

    @GetMapping("/auth-code-oauth")
    Mono<String> useOauthWithAuthCode(@RegisteredOAuth2AuthorizedClient("myclient") OAuth2AuthorizedClient authorizedClient) {
        Mono<String> retrievedResource = webClient.get()
            .uri(RESOURCE_URI)
            .attributes(oauth2AuthorizedClient(authorizedClient))
            .retrieve()
            .bodyToMono(String.class);
        return retrievedResource.map(string -> "We retrieved the following resource using Oauth: " + string);
    }
}

5- Now call the /auth-code-oauth endpoint. We get redirected to the Authentication login form, approve the required scopes, and after being redirected to the specified redirect-uri (/authorize/oauth2/code/myclient) the application retrieves the token, and we are redirected to the root ("/") url, instead of the endpoint that I actually called in the first place. If I make the call to the /auth-code-oauth endpoint again afterwards, the retrieved response is the expected, since no authentication process is carried out at this point.

Included a link to the sample by the end of the description

Version

Spring Boot 2.1.1.RELEASE Spring Security: 5.1.2.RELEASE

Sample

https://github.com/rozagerardo/samples

Comment From: rozagerardo

It seems the SPRING_SECURITY_SAVED_REQUEST session attribute is not saved by any filter for the oauth2Client() configuration. After comapring with the non-reactive version, I see that they behave differently. On the non-reactive side, the HttpSecurity uses an OAuth2ClientConfigurer when calling oauth2Client(), which seems to include an OAuth2AuthorizationRequestRedirectFilter in the SecurityWebFilterChain to save that session attribute. The webflux version, on the other hand, uses a ServerHttpSecurity, which relies on the OAuth2ClientSpec. This adds an OAuth2AuthorizationRequestRedirectWebFilter to the chain, but it stores only the AUTHORIZATION_REQUEST web session attribute, not the SPRING_SECURITY_SAVED_REQUEST. Then the RedirectServerAuthenticationSuccessHandler used by the OAuth2AuthroizationCodeGrantWebFilter (added to the chain by the oauth2client() configuration too) can't find it to redirect to the appropiate address

Comment From: rwinch

Thanks for the report and anyalysis @rozagerardo! Would you be interested in submitting a PR for this?

Comment From: rozagerardo

Thanks for the quick response @rwinch Sure, I'll be glad to work on this :) This will be my first contribution to the project, so it might take me a little bit longer than expected, to get familiarized with the contributor's guidelines I'll come back as soon as I have the PR ready

Comment From: rwinch

Thanks @rozagerardo! Let us know if you run into any issues and we will do our best to help

Comment From: rozagerardo

Thanks @rwinch ! I now created PR #6418 to solve this. I'm looking forward to you comments, and please let me know if I can do anything else to help you :) cheers!

Comment From: rozagerardo

Thanks for the support @rwinch it's been a nice first experience contributing to this project :) I'd like to get involved more with the Spring project, so I'll try to pick another task soon (either from spring-security or from any other project). Any suggestion or feedback for me is always appreciated. Cheers!

Comment From: rwinch

Thanks again for your contribution! If you are looking for more tasks to work on, you can find ideal tickets with the Help Wanted label. Of course if you find something else, please just let us know and we can help determine if it is something we are interested in contributions for.