Spring Security和OAuth2之间Principal接口的两种不同实现

时间:2019-03-09 13:28:35

标签: java spring-boot spring-security oauth-2.0 spring-security-oauth2

曾经有一个由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次,非常乏味。
解决方案是我必须像上面的代码一样重写,或者进行其他我不知道的事情?

1 个答案:

答案 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();

}