spring-bootservletsoauth-2.0pkce

PKCE for confidential clients in Spring 5 (non-reactive)


I'm trying to enable PKCE on an oAuth client in Spring Boot 5. The examples I can find are for reactive client, looking something like this:

SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http,    ReactiveClientRegistrationRepository clientRegistrationRepository) {
        DefaultServerOAuth2AuthorizationRequestResolver pkceResolver = new DefaultServerOAuth2AuthorizationRequestResolver(clientRegistrationRepository);
        pkceResolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());

http.oauth2Login(login -> login
    .authorizationRequestResolver(pkceResolver)

I tried converting this to the servlet equivalent, but the oAuthLoginConfigurer for that doesn't have an authorizationRequestResolver method to set the PKCE resolver.

This is where I got to:

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http
          ,ClientRegistrationRepository repo
  ) 
  throws Exception {

    var resolver = new DefaultOAuth2AuthorizationRequestResolver(repo,"https://myoauthserver.com");
    resolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());
    
    http
        .authorizeRequests(a -> a
            .antMatchers("/").permitAll()
            .anyRequest().authenticated())
        .oauth2Login(); // doesn't have the authorizationRequestResolver method like reactive



    return http.build();
  }

Any ideas how to make this work for servlet?


Solution

  • Ok, I've figured out and thought I'd better not leave this question hanging for poor souls in the future (ie. me when I forget how it works).

    Here is the magic bean:

    @Configuration
    public class SecurityConfiguration {
    
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http, ClientRegistrationRepository repo)
          throws Exception {
    
        var base_uri = OAuth2AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI;
        var resolver = new DefaultOAuth2AuthorizationRequestResolver(repo, base_uri);
    
        resolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());
    
        http
            .authorizeRequests(a -> a
                .antMatchers("/").permitAll()
                .anyRequest().authenticated())
            .oauth2Login(login -> login.authorizationEndpoint().authorizationRequestResolver(resolver));
    
        http.logout(logout -> logout
            .logoutSuccessUrl("/"));
    
        return http.build();
      }
    }