Spring OAuth (OAuth2): How can I get the client credentials in a Spring MVC controller?
Solution 1
I found a reasonable solution based on @luke-taylor answer.
@RequestMapping(method = GET)
public List<Place> read(OAuth2Authentication auth) {
auth.getOAuth2Request().getClientId()
}
Solution 2
The client identity is available from the Authentication
object which you can either cast the principal to, or get directly from the thread-local security context. Something like
Authentication a = SecurityContextHolder.getContext().getAuthentication();
String clientId = ((OAuth2Authentication) a).getAuthorizationRequest().getClientId();
If you don't want to put that code directly into your controller, you can implement a separate context accessor as described in this answer and inject that into it instead.
Solution 3
Fleshing out the HandlerMethodArgumentResolver
option a bit more. In order to support the following:
@RequestMapping(
value = WEB_HOOKS,
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public List<SomeDTO> getThoseDTOs(@CurrentClientId String clientId)
{
// Do something with clientId - it will be null if there was no authentication
}
We'll need the HandlerMethodArgumentResolver
registered with our Application Context (for me this was inside a WebMvcConfigurerAdapter
). My HandlerMethodArgumentResolver
looks like this:
public class OAuth2ClientIdArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(CurrentClientId.class) != null
&& parameter.getParameterType().equals(String.class);
}
@Override
public Object resolveArgument(
MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory)
throws Exception
{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication == null) {
return null;
}
String clientId = null;
if (authentication.getClass().isAssignableFrom(OAuth2Authentication.class)) {
clientId = ((OAuth2Authentication) authentication).getOAuth2Request().getClientId();
}
return clientId;
}
}
And the @interface
definition:
@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurrentClientId {
}
wandi.darko
Updated on November 12, 2021Comments
-
wandi.darko over 2 years
In this snippet:
@RequestMapping(method = GET) public List<Place> read(Principal principal) { principal.getName(); }
principal.getName()
gives me the user identification but I need a way to receive the client credentials (client => the app who is using my API). How can I do this? -
tao about 8 yearsnice answer, except the post date is little old. The spring boot 1.3.3 is using getOAuth2Request() instead of getAuthorizationRequest()
-
Dimitri Kopriwa over 7 yearsThis returned me the Principal user and not the client id application
-
Cataclysm over 6 yearsUpdated version :
auth.getOAuth2Request().getClientId()
-
Wafula Samuel over 4 yearsHow about client secret?