In order to add a custom parameter to the default authorization request, an application follows the delegator pattern:

OAuth2AuthorizationRequestResolver delegate =
        new DefaultOAuth2AuthorizationRequestResolver
                (this.clients, "/oauth2/authorization");
return new OAuth2AuthorizationRequestResolver() {
    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
        return resolve(request, request.getServerName());
    }

    @Override
    public OAuth2AuthorizationRequest resolve
            (HttpServletRequest request, String clientRegistrationId) {
        OAuth2AuthorizationRequest authorizationRequest = 
                delegate.resolve(request);
        if (authorizationRequest == null) {
            return authorizationRequest;
        }
        Map<String, Object> parameters = new HashMap<>      
                (authorizationRequest.getAdditionalParameters());
        parameters.put("kc_idp_hint", clientRegistrationId);
        return OAuth2AuthorizationRequest.from(authorizationRequest)
                .additionalParameters(parameters)
                .build();
    }
};

It's quite easy to forget that the additionalParameters method overrides any parameters already set by the default implementation:

// ...
Map<String, Object> parameters = new HashMap<>      
        (authorizationRequest.getAdditionalParameters()); // <-- easy to forget
parameters.put("kc_idp_hint", clientRegistrationId);
return OAuth2AuthorizationRequest.from(authorizationRequest)
        .additionalParameters(parameters)
        .build();

This can be simplified by introducing a new configuration method that is also in line with other builders in Spring Security:

public Builder additionalParameters(Consumer<Map<String, Object>> parametersConsumer)

Given that method, the configuration would change to:

return OAuth2AuthorizationRequest.from(authorizationRequest)
        .additionalParameters(params -> params
                .put("kc_idp_hint", clientRegistrationId))
        .build();

Which also has the benefit that there is less code for the application.

Comment From: jzheaux

Closed in favor of #7748