更新时间:2023-02-16 08:12:07
要解决此问题,请让我通过一个首先是建筑背景。通过 @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.