javaspringspring-bootoauth-2.0

How to set the principal name of a Spring Security OAuth2AuthorizedClient using access token response?


I am currently playing around with Spring Security 6's OAuth2 Client in Spring Boot 3.

I am using an authorization_code grant which is exchanged for an access token using the following security config:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((authorize) -> authorize
                .anyRequest().authenticated()
        ).oauth2Client(oauth2 -> oauth2
                .authorizationCodeGrant(codeGrant -> codeGrant
                                .accessTokenResponseClient(new DefaultAuthorizationCodeTokenResponseClient())))
                .formLogin(Customizer.withDefaults());
        return http.build();
    }
}

The token response of the OAuth2 provider I am using is:

(This is an example, provided by the provider)

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
    "access_token":"2YotnFZFEjr1zCsicMWpAA",
    "token_type":"Bearer",
    "expires_in":3600,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
    "refresh_expires_in": 7776000
    "membership_id":"4352344"
}

My issue is that I need the principal name for the associated OAuth2AuthorizedClient to match the membership_id provided in the token response. However, I have no idea how to do this.

Any help is much appreciated.


Solution

  • Spring has this builtin to its configuration feature.

    You can either added a userInfoUri and a userNameAttributeName to the application.yml file or you can add it via the ClientRegistration Builder

    return ClientRegistration.withRegistrationId("bungie")
                    .clientId("id")
                    .clientSecret("secret")
                    .authorizationUri("https://www.bungie.net/en/OAuth/Authorize")
                    .tokenUri("https://www.bungie.net/platform/app/oauth/token/")
                    .userInfoUri("https://www.bungie.net/Platform/User/GetMembershipsForCurrentUser/")
                    .userNameAttributeName("primaryMembershipId")
                    .clientName("bungie")
                    .redirectUri("redirect")
                    .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                    .build();
    

    Please note that for using this with the Bungie OAuth2 Service you have to customize the DefaultOAuth2UserService and the DefaultOAuth2UserRequestEntityConverter to support proper parsing and for adding the X-API-Key to the user info request