曾经有一个由Spring Security配置的整体Java应用程序。每当我想获得经过身份验证的用户时,org.springframework.serurity.authentication.UsernamePasswordAuthenticationToken
对象都会给我这样的信息:
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
直到我将配置从 Spring Security 更改为 Oauth2 为止,这段代码才能正常工作。
为了进行OAuth2,org.springframework.serurity.oauth2.provider.OAuth2Authentication
对象为我提供了经过身份验证的用户,如下所示:
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
return linkedHashMap.get("principal");
因此SecurityContextHolder.getContext().getAuthentication().getPrincipal()
的结果是 OAuth2 和 Spring Security 之间的区别。
问题出在哪里:
我的问题是
1-我必须重写包含SecurityContextHolder.getContext().getAuthentication().getPrincipal()
with
Object obj = SecurityContextHolder.getContext().getAuthentication();
if (obj instanceof OAuth2Authentication) {
OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
linkedHashMap.get("principal");
LinkedHashMap result = linkedHashMap.get("principal");
User user = new User();
user.setId((Integer)result.get("id"));
user.setName((String)result.get("name"));
//As same way to set other its attributes@@@@@@@@@@
return user;
} else
return (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
2-从上面用 @@@@@@@@@@@ 标记的代码中可以看出,User对象的字段数接近20,因此我必须重复user.setField(result.get("filed"))
20次,非常乏味。
解决方案是我必须像上面的代码一样重写,或者进行其他我不知道的事情?
答案 0 :(得分:2)
是的,的确,Spring Security和Spring Oauth2的两种身份验证都不同。您可以创建某种类型的@Service或@Component类,该类可以处理您所需要的东西。然后可以在需要时将其注入/自动接线。因此,基本上,这个新类成为检索您的校长的唯一事实来源。如果您碰巧再次更改安全性实现,则代码不会受到影响,因为安全性处理服务已通过新界面抽象化了。
请参见以下示例:
@Service
public class Oauth2PrincipalService implements PrincipalService {
public User retreivePrincipalUser(){
//retreive user stuff here as you need using the oauth2 code you provided..
}
}
public interface PrincipalService {
User retreivePrincipalUser();
}