简体   繁体   English

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

[英]Two difference implementation of Principal interface between Spring Security & OAuth2

There had been being a monolithic java-application that is configured by Spring Security. 曾经有一个由Spring Security配置的整体Java应用程序。 Whenever I want to get the authenticated user, the org.springframework.serurity.authentication.UsernamePasswordAuthenticationToken object gives me like this: 每当我想获得经过身份验证的用户时, org.springframework.serurity.authentication.UsernamePasswordAuthenticationToken对象都会给我这样的信息:

User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

This piece of code had been working correctly until I changed the configuration from Spring Security to Oauth2 . 在我将配置从Spring Security更改为Oauth2之前,这段代码一直可以正常工作。
In order to OAuth2, org.springframework.serurity.oauth2.provider.OAuth2Authentication object gives me the authenticated user like this: 为了OAuth2, org.springframework.serurity.oauth2.provider.OAuth2Authentication对象为我提供了经过身份验证的用户,如下所示:

OAuth2Authentication oAuth2Authentication = (OAuth2Authentication) SecurityContextHolder.getContext().getAuthentication();
LinkedHashMap linkedHashMap = (LinkedHashMap) oAuth2Authentication.getUserAuthentication().getDetails();
return linkedHashMap.get("principal");

So the result of SecurityContextHolder.getContext().getAuthentication().getPrincipal() is difference between OAuth2 and Spring Security . 因此, SecurityContextHolder.getContext().getAuthentication().getPrincipal()OAuth2Spring Security之间的区别。
What is the problem: 问题是什么:
My problem is that 我的问题是
1- I have to rewrite every where contains SecurityContextHolder.getContext().getAuthentication().getPrincipal() 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- As it is seen in above code that is marked by @@@@@@@@@ , the number of field of User object is near to 20, so I have to repeat user.setField(result.get("filed")) 20 times and it is so tedious. 2-如在上面由@@@@@@@@@@标记的代码中看到的,User对象的字段数接近20,因此我必须重复user.setField(result.get("filed")) 20次,这是如此乏味。
The solution is that I have to either rewrite as same as above code or other thing that I do not know? 解决的办法是我必须像上面的代码一样重写或进行其他我不知道的事情?

Yes, indeed, both of those Authentications are different between Spring Security and Spring Oauth2. 是的,的确,Spring Security和Spring Oauth2之间的这两种身份验证都是不同的。 You could create some sort of @Service or @Component class that handles giving you back what you are looking for. 您可以创建某种类型的@Service或@Component类,该类可以处理您所需要的东西。 This can then be injected/autowired where ever you need it. 然后可以在需要时将其注入/自动接线。 So basically, this new class becomes the single source of truth for retrieving your principal. 因此,基本上,这个新类成为检索您的校长的唯一事实来源。 If you happen to change the security implementation again, your code should not be affected because the security handling service is abstracted away by a new interface. 如果您碰巧再次更改安全性实现,则代码不会受到影响,因为安全性处理服务已通过新接口抽象化。

See sample below: 请参阅以下示例:

@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();

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM