我有一个配置有@EnableResourceServer
注释的资源服务器,它通过user-info-uri
参数引用授权服务器,如下所示:
security:
oauth2:
resource:
user-info-uri: http://localhost:9001/user
授权服务器/用户端点返回其扩展名,org.springframework.security.core.userdetails.User
例如,电子邮件:
{
"password":null,
"username":"myuser",
...
"email":"[email protected]"
}
每当访问某些资源服务器端点时,Spring都会通过调用授权服务器的/user
端点来验证幕后的访问令牌,并实际上返回丰富的用户信息(其中包含电子邮件信息,我已经使用Wireshark进行了验证)。
因此,问题是,如何在不显式第二次调用授权服务器/user
端点的情况下获取此自定义用户信息。授权后,Spring是否将其存储在资源服务器上的本地位置?或者,如果没有可用的现成方法,实现这种用户信息存储的最佳方法是什么?
解决方案是实现自定义 UserInfoTokenServices
只需将您的自定义实现作为Bean提供即可,它将代替默认的实现使用。
在此UserInfoTokenServices内部,您可以构建所需的对象principal
。
此UserInfoTokenServices用于从/users
授权服务器的端点的响应中提取UserDetails 。如您所见
private Object getPrincipal(Map<String, Object> map) {
for (String key : PRINCIPAL_KEYS) {
if (map.containsKey(key)) {
return map.get(key);
}
}
return "unknown";
}
PRINCIPAL_KEYS
默认情况下,仅提取中指定的属性。那正是您的问题。您不仅需要提取用户名或您的属性命名的任何内容。因此,寻找更多的钥匙。
private Object getPrincipal(Map<String, Object> map) {
MyUserDetails myUserDetails = new myUserDetails();
for (String key : PRINCIPAL_KEYS) {
if (map.containsKey(key)) {
myUserDetails.setUserName(map.get(key));
}
}
if( map.containsKey("email") {
myUserDetails.setEmail(map.get("email"));
}
//and so on..
return myUserDetails;
}
接线:
@Autowired
private ResourceServerProperties sso;
@Bean
public ResourceServerTokenServices myUserInfoTokenServices() {
return new MyUserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
}
!!使用Spring Boot 1.4进行更新变得越来越容易了!
在Spring Boot 1.4.0 中引入了PrincipalExtractor。应该实现此类以提取自定义主体(请参阅Spring Boot 1.4发行说明)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句