Search code examples
springspring-bootspring-securityoauth-2.0

Code verifier not sent with spring reactive security


I've been trying to set up twitter oauth2 PKCE authentification with spring boot. The issue is that the code_verifier parameter is not being picked up by spring security. Do I have to configure a bean so that the code verifier gets picked up? Is there a way to customize a ReactiveOAuth2AccessTokenResponseClient to customize to body send to the token endpoint ?

Here is my spring security config, :

    public SecurityWebFilterChain securityWebFilterChain(
            ServerHttpSecurity http) {
        return http.authorizeExchange()
                .anyExchange().authenticated()
                .and().oauth2Login().and().build();
    }
  security:
    oauth2:
      client:
        registration:
          twitter:
            client-id: xxx
            client-secret: xxx
            authorization-grant-type: authorization_code
            redirect-uri: http://localhost:8080/login/oauth2/code/twitter
        provider:
          twitter:
            authorization-uri: https://twitter.com/i/oauth2/authorize?response_type=code&client_id=xxx&redirect_uri=http://localhost:8080/login/oauth2/code/twitter&scope=tweet.read%20users.read%20follows.read%20follows.write&code_challenge=challenge&code_challenge_method=plain
            token-uri: https://api.twitter.com/2/oauth2/token
            user-info-uri: https://api.twitter.com/2/users/me
            user-name-attribute: data

Solution

  • For people still looking for an answer: You can customize the token request body by overriding the WebClientReactiveAuthorizationCodeTokenResponseClient bean and use the setParameter method. Here is an example:

    @Bean
    public WebClientReactiveAuthorizationCodeTokenResponseClient webClientReactiveAuthorizationCodeTokenResponseClient() {
        WebClientReactiveAuthorizationCodeTokenResponseClient webClientReactiveAuthorizationCodeTokenResponseClient =
                new WebClientReactiveAuthorizationCodeTokenResponseClient();
            webClientReactiveAuthorizationCodeTokenResponseClient.setParametersConverter(source -> {
            MultiValueMap<String, String> parameters = new LinkedMultiValueMap();
            parameters.add("grant_type", source.getGrantType().getValue());
            //...
            return parameters;
        });
    
        return webClientReactiveAuthorizationCodeTokenResponseClient;
    }