Spring OAuth(OAuth2):如何在Spring MVC控制器中获取客户端凭据?

wan*_*rko 17 spring spring-mvc spring-security oauth-provider oauth-2.0

在这个片段中:

@RequestMapping(method = GET)
public List<Place> read(Principal principal) {
  principal.getName(); 
}
Run Code Online (Sandbox Code Playgroud)

principal.getName()给了我用户身份,但我需要一种方法来接收客户端凭据(client =>使用我的API的应用程序).我怎样才能做到这一点?

Sha*_*eep 21

客户端标识可从Authentication对象获得,您可以将该主体转换为主体,也可以直接从线程本地安全上下文获取.就像是

Authentication a = SecurityContextHolder.getContext().getAuthentication();

String clientId = ((OAuth2Authentication) a).getAuthorizationRequest().getClientId();
Run Code Online (Sandbox Code Playgroud)

如果您不想将该代码直接放入控制器,则可以按照本答案中的描述实现单独的上下文访问器,并将其注入其中.

  • 很好的答案,除了发布日期有点旧。spring boot 1.3.3 使用 getOAuth2Request() 而不是 getAuthorizationRequest() (2认同)

wan*_*rko 15

我找到了一个基于@ luke-taylor答案的合理解决方案.

@RequestMapping(method = GET)
public List<Place> read(OAuth2Authentication auth) {
  auth.getOAuth2Request().getClientId()
}
Run Code Online (Sandbox Code Playgroud)

  • 更新版本:`auth.getOAuth2Request().getClientId()` (2认同)

Mic*_*ler 5

充实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
}
Run Code Online (Sandbox Code Playgroud)

我们需要在HandlerMethodArgumentResolver我们的应用程序上下文中注册(对我而言,这是在一个内部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;
    }

}
Run Code Online (Sandbox Code Playgroud)

@interface定义:

@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurrentClientId {

}
Run Code Online (Sandbox Code Playgroud)