如何将OAuth 2令牌映射到资源服务器中的UserDetails对象? [英] How do I map OAuth 2 token to UserDetails object in a resource server?

查看:2539
本文介绍了如何将OAuth 2令牌映射到资源服务器中的UserDetails对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个独立的Spring Boot应用程序,一个用作OAuth 2授权服务器,另一个用作资源服务器。我在资源服务器中使用Spring的 RemoteTokenServices 来检查授权服务器中的令牌。现在,我正在尝试在我的资源服务器应用程序中定义受保护的控制器代码,但我不确定如何将 UserDetails 类映射到通过OAuth提供的身份验证主体2机制。

I have 2 separate Spring Boot applications, one serving as an an OAuth 2 authorization server, and the other as resource server. I'm using Spring's RemoteTokenServices in my resource server to check tokens from the authorization server. Now, I'm trying to define protected controller code in my resource server application, but I'm not sure how to map the UserDetails class to the authentication principal provided through the OAuth 2 mechanism.

我使用自定义 TokenEnhancer 设置了授权服务器,为令牌添加了更多详细信息,以便 / oauth / check_token?token =< token> 返回自定义字段,我想将其映射到资源服务器控制器。

I have set up my authorization server with a custom TokenEnhancer that adds more details to the token such that /oauth/check_token?token=<token> returns with custom fields, which I want to map to my resource server controllers.

在一个更加单一的设置中,授权服务器也是资源服务器,我可以定义以这种方式使用经过身份验证的主体的控制器方法:

In a more monolithic setup where the authorization server is also the resource server, I can define controller methods that make use of the authenticated principal this way:

//User implements UserDetails
public Map<String, Object> getResource(@AuthenticationPrincipal User user) {
    //code that uses the user object
}

然而,在更分散的方法中,这似乎并不直接。映射失败, user 参数最终成为空对象。我尝试使用以下方法:

However, this doesn't seem to work as straight forward in a more distributed approach. The mapping fails, and the user parameter ends up being a null object. I tried using the following approach:

public Map<String, Object> getResource(Authentication authentication) {
    //code that uses the authentication object
}

虽然上面的代码成功映射了身份验证详细信息,但它没有为我提供直接访问我通过 TokenEnhancer 设置的自定义字段的方法。 。我似乎无法从Spring文档中找到任何关于此的内容。

While the code above successfully maps the authentication details, it doesn't provide a way for me to directly access the custom fields I've set through the TokenEnhancer I mentioned earlier. I can't seem to find anything from the Spring docs regarding this.

推荐答案

要解决此问题,请让我通过一个首先是建筑背景。通过 @AuthenticationPrincipal 自动映射的 UserDetails 对象来自 principal 活动身份验证对象的字段。资源服务器控制器可以访问 OAuth2Authencation 对象,该对象是Spring OAuth2安全框架的身份验证的专用实例,只需将其声明为方法参数的一部分即可。

To resolve the issue, let me go through a bit of architectural background first. The UserDetails object automatically mapped through the @AuthenticationPrincipal comes from the principal field of the active Authentication object. A resource server controller has access to an OAuth2Authencation object, which is a specialized instance of Authentication for Spring OAuth2 security framework, just by simply declaring it as part of the method parameters.

public void controllerMethod(OAuth2Authentication authentication) {
    //controller definition
}

知道这一点,问题现在转移到如何确保 getPrincipal()身份验证对象中的c $ c>方法是我的自定义 UserDetails 类的实例。我在资源服务器应用程序中使用的 RemoteTokenServices 使用 AccessTokenConverter 的实例来解释授权服务器发送的令牌详细信息。默认情况下,它使用 DefaultAccessTokenConverter ,它只将身份验证主体设置为用户名,即 String 。此转换器使用 UserAuthenticationConverter 将来自授权服务器的数据转换为身份验证的实例。这就是我需要自定义的内容:

Knowing this, the problem now shifts to how to make sure that the getPrincipal() method in the Authentication object is an instance of my custom UserDetails class. The RemoteTokenServices I use in the resource server application uses an instance of AccessTokenConverter to interpret token details sent by the authorization server. By default, it uses DefaultAccessTokenConverter, which just sets the authentication principal as the username, which is a String. This converter makes use of UserAuthenticationConverter to convert the data coming from the authorization server into an instance of Authentication. This is what I needed to customize:

DefaultAccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
tokenConverter.setUserTokenConverter(new DefaultUserAuthenticationConverter() {

    @Override
    public Authentication extractAuthentication(Map<String, ?> map) {
        Authentication authentication = super.extractAuthentication(map);
        // User is my custom UserDetails class
        User user = new User();
        user.setSpecialKey(map.get("specialKey").toString());
        return new UsernamePasswordAuthenticationToken(user,
                authentication.getCredentials(), authentication.getAuthorities());
    }

});
tokenServices.setAccessTokenConverter(tokenConverter);

完成所有这些设置后, @AuthenticationPrincipal 机制现在按预期工作。

With all these set up, the @AuthenticationPrincipal mechanism now works as expected.

这篇关于如何将OAuth 2令牌映射到资源服务器中的UserDetails对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆