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
}
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
.