Search code examples
spring-securityoauth-2.0spring-security-oauth2

Unable to add parameters to Spring OAuth2UserRequest


I want to be able to pass additional parameters from the client to the OAuth2 user service. Following this Spring reference https://docs.spring.io/spring-security/site/docs/5.1.1.RELEASE/reference/htmlsingle/#oauth2Client-authorization-request-resolver, I am able to add the additional parameter to the OAuth2AuthorizationRequest. When I try to retrieve the parameter in my custom DefaultOAuth2UserService it is no longer part of the OAuth2UserRequest.

I think the issue is related to the resolve method of OAuth2AuthorizationRequest being called twice, the second time the authorizationRequest is null. See debug log below

Any suggestions on how to troubleshoot / fix this issue?

Client Request

http://localhost:8080/oauth2/authorize/github?redirect_uri=http://localhost:3000/oauth2/redirect&action=signup

Detailed Log

CustomAuthorizationRequestResolver : in CustomAuthorizationRequestResolver.resolve() authorizationRequest is [Initialized]
CustomAuthorizationRequestResolver: action parameter from HttpServletRequest is [signup]
CustomAuthorizationRequestResolver: number of additional parameters added to OAuth2AuthorizationRequest is [1]
CustomAuthorizationRequestResolver: in CustomAuthorizationRequestResolver.resolve() authorizationRequest is [null]
CustomOAuth2UserService: in CustomOAuth2UserService.loadUser() size of additional parameters [0]

CustomAuthorizationRequestResolver

public class CustomAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver {
    private final static Logger logger = LoggerFactory.getLogger(CustomAuthorizationRequestResolver.class);
    private final OAuth2AuthorizationRequestResolver defaultAuthorizationRequestResolver;

    public CustomAuthorizationRequestResolver(ClientRegistrationRepository clientRegistrationRepository) {
        this.defaultAuthorizationRequestResolver = new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository,
                "/oauth2/authorize");
    }

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest request) {
        OAuth2AuthorizationRequest authorizationRequest = this.defaultAuthorizationRequestResolver.resolve(request);
        logger.debug("in CustomAuthorizationRequestResolver.resolve() authorizationRequest is [{}]", 
            authorizationRequest == null ? "null" : "Initialized");
        return authorizationRequest != null ? customAuthorizationRequest(request, authorizationRequest) : null;
    }

    @Override
    public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) {
        OAuth2AuthorizationRequest authorizationRequest = this.defaultAuthorizationRequestResolver.resolve(
                request, clientRegistrationId);
        return authorizationRequest != null ? customAuthorizationRequest(request, authorizationRequest) : null;
    }

    private OAuth2AuthorizationRequest customAuthorizationRequest(HttpServletRequest request,
            OAuth2AuthorizationRequest authorizationRequest) {
        String action = request.getParameter("action");
        logger.debug("action parameter from HttpServletRequest is [{}]", action);

        Map<String, Object> additionalParameters = new LinkedHashMap<>(authorizationRequest.getAdditionalParameters());
        additionalParameters.put("action", action);

        OAuth2AuthorizationRequest rtn = OAuth2AuthorizationRequest.from(authorizationRequest).additionalParameters(
                additionalParameters).build();

        logger.debug("number of additional parameters added to OAuth2AuthorizationRequest is [{}]", rtn.getAdditionalParameters()
                .size());

        return rtn;
    }
}

CustomOAuth2UserService

public class CustomOAuth2UserService extends DefaultOAuth2UserService {
    private final Logger logger = LoggerFactory.getLogger(CustomOAuth2UserService.class);

    @Autowired
    private UserRepository userRepository;

    @Override
    public OAuth2User loadUser(OAuth2UserRequest oAuth2UserRequest) throws OAuth2AuthenticationException {
        OAuth2User oAuth2User = super.loadUser(oAuth2UserRequest);

        logger.debug("in CustomOAuth2UserService.loadUser() size of additional parameters [{}]", oAuth2UserRequest
                .getAdditionalParameters().size());
        // other processing
    }
    
    // other methods
}

Solution

  • The OAuth2AuthorizationRequest and OAuth2UserRequest are different requests to different endpoints.

    The OAuth2AuthorizationRequest represents the request to http://localhost:8080/oauth2/authorize/github?redirect_uri=http://localhost:3000/oauth2/redirect&action=signup, while the OAuth2UserRequest represents the request to, for example, http://localhost:3000/userinfo.

    The additional parameter was never part of the OAuth2UserRequest.