解决方案是实施自定义UserInfoTokenServices
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/UserInfoTokenServices.java https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/oauth2/resource/UserInfoTokenServices.java
只需将您的自定义实现作为 Bean 提供,它将被用来代替默认的实现。
在此 UserInfoTokenServices 内,您可以构建principal
就像你想要的那样。
此 UserInfoTokenServices 用于从响应中提取 UserDetails/users
您的授权服务器的端点。正如你所看到的
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;
}
Wiring:
@Autowired
private ResourceServerProperties sso;
@Bean
public ResourceServerTokenServices myUserInfoTokenServices() {
return new MyUserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
}
!!使用 Spring Boot 1.4 更新事情变得更容易!
使用 Spring Boot 1.4.0主要提取器 http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/api/org/springframework/boot/autoconfigure/security/oauth2/resource/PrincipalExtractor.html被介绍了。应该实现此类来提取自定义主体(请参阅Spring Boot 1.4 发行说明 https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.4-Release-Notes#principalextractor).