Spring OAuth (OAuth2):如何在 Spring MVC 控制器中获取客户端凭据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12464042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring OAuth (OAuth2): How can I get the client credentials in a Spring MVC controller?
提问by wandi.darko
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?
principal.getName()给了我用户标识,但我需要一种方法来接收客户端凭据(客户端 => 使用我的 API 的应用程序)。我怎样才能做到这一点?
采纳答案by wandi.darko
I found a reasonable solution based on @luke-taylor answer.
我根据@luke-taylor 的回答找到了一个合理的解决方案。
@RequestMapping(method = GET)
public List<Place> read(OAuth2Authentication auth) {
auth.getOAuth2Request().getClientId()
}
回答by Shaun the Sheep
The client identity is available from the Authenticationobject which you can either cast the principal to, or get directly from the thread-local security context. Something like
客户端标识可从Authentication对象中获得,您可以将主体转换为该对象,也可以直接从线程本地安全上下文中获取。就像是
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 answerand inject that into it instead.
如果您不想将该代码直接放入您的控制器中,您可以实现一个单独的上下文访问器,如本答案中所述,并将其注入其中。
回答by Michael Ressler
Fleshing out the HandlerMethodArgumentResolveroption a bit more. In order to support the following:
进一步充实HandlerMethodArgumentResolver选项。为了支持以下内容:
@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 HandlerMethodArgumentResolverregistered with our Application Context (for me this was inside a WebMvcConfigurerAdapter). My HandlerMethodArgumentResolverlooks like this:
我们需要在HandlerMethodArgumentResolver我们的应用程序上下文中注册(对我来说这是在 a 中WebMvcConfigurerAdapter)。我的HandlerMethodArgumentResolver看起来像这样:
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 @interfacedefinition:
和@interface定义:
@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurrentClientId {
}
回答by Imtiaz Shakil Siddique
A simple way to retrieve the clientIdis loading the currently authenticated principal. The principalcan be defined directly as a method argument and it will be correctly resolved by the framework.
检索 的一种简单方法clientId是加载当前经过身份验证的principal. 的principal可以直接定义为方法参数,它会被框架正确地解析。
Here is an example:
下面是一个例子:
@RequestMapping(method = RequestMethod.GET)
public Map<String, String> getUserInfo(Principal principal) {
OAuth2Authentication oauth = (OAuth2Authentication) principal;
Map<String, String> userInfo = new LinkedHashMap<>();
userInfo.put("username", principal.getName());
userInfo.put("clientId", oauth.getOAuth2Request().getClientId());
return userInfo;
}

