在安全上下文中保存 Oauth2RestTemplate/Client 存储

Posted

技术标签:

【中文标题】在安全上下文中保存 Oauth2RestTemplate/Client 存储【英文标题】:Saving Oauth2RestTemplate/Client storing in Security Context 【发布时间】:2020-10-03 03:57:40 【问题描述】:

我正在使用 OAuth2 保护我的 Web 应用程序。我有一个自定义身份验证提供程序,它将 OAuth2Client(OAuth2RestTemplate) 存储在安全上下文中。

CustomAuthenticationProvide



@Component
public class CustomAuthenticationProvider implements AuthenticationProvider 

    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException 

        String name = authentication.getName();
        String password = authentication.getCredentials().toString();


        try 
            ResourceOwnerPasswordResourceDetails passwordResourceDetails =
                    (ResourceOwnerPasswordResourceDetails) new OAuth2Client(name, password).getResource();
            passwordResourceDetails.setUsername(name);
            passwordResourceDetails.setPassword(password);


            OAuth2Client client = new OAuth2Client(passwordResourceDetails);
            User user = client.getUser();
            if (!name.equals(user.getMail())) 
                throw new OAuth2AccessDeniedException();
            
            return new AuthToken(name, password, new ArrayList<>(), user, client);
         catch (OAuth2AccessDeniedException ex) 
            ex.printStackTrace();
            return null;
        
    

    @Override
    public boolean supports(Class<?> aClass) 
        return aClass.equals(UsernamePasswordAuthenticationToken.class);
    

AuthToken(认证对象的实现)


public class AuthToken extends UsernamePasswordAuthenticationToken 
    private User user;
    private OAuth2Client client;

    AuthToken(Object principal, String credentials, Collection<? extends GrantedAuthority> authorities, User user, OAuth2Client client) 
        super(principal, credentials, authorities);
        this.user = user;
        this.client = client;
    
    AuthToken(String principal, String credentials) 
        super(principal, credentials);
    

    public User getUser() 
        return user;
    

    public OAuth2Client getClient() 
        return client;
    

首先我想知道这是否安全?上次我登录的时候。过了一会儿,我看到了在我之后登录的用户的命令。我的下一个问题是,是否有更好/更漂亮的解决方案。我正在使用 Spring Security OAuth2 文档,但我没有得到它的工作。我为所有用户拥有相同的客户端。

示例控制器映射

 @GetMapping(value = "/orders")
    public ModelAndView orders(AuthToken token, HttpServletRequest request) 
      if (token != null) 
            request.getSession().setAttribute("userAcc", token.getUser());
        
        user = token.getUser();

        List<Statistics> statistics = new ArrayList<>();
        try 
            List<Order> orders = Arrays.asList(token.getClient().getOrders());
            // @TODO Daten Liefern
            for (Order order : orders) 
                if(!order.getUserid().equals(token.getUser().getId()))
                    return new ModelAndView("redirect:/logout");
                
                Statistics st = new Statistics(order.getProperties(), order.getId());
                statistics.add(st);
            
         catch (Exception ex) 
            ex.printStackTrace();
        

        List<Statistics> statistics_back = new ArrayList<>();
        for (int i = statistics.size() - 1; i >= 0; i--) 
            statistics_back.add(statistics.get(i));
        
        return new ModelAndView("my_orders")
                .addObject("statistics", statistics_back);

    

【问题讨论】:

【参考方案1】:

基本上 OAuth2 是在您的应用程序中授权外部应用程序或 API。假设您在应用程序中使用 Google Docs,那么您可能必须授权您的客户端访问 Google 提供的 Docs,方法是将客户端重定向到 Google,并向 google 进行身份验证并授权从您的应用程序访问 Docs。获得授权后,您将获得一个授权码,无论何时客户想要访问文档,都将使用该授权码进行访问。

如果您想对您的应用程序进行完美的身份验证,那么我建议您从客户端收集用户名和密码,并将其存储在 spring security 提供的加密和解密的数据库中。

在我看来,OAuth 不会是一个完美的身份验证平台。

【讨论】:

以上是关于在安全上下文中保存 Oauth2RestTemplate/Client 存储的主要内容,如果未能解决你的问题,请参考以下文章

如何安全地删除未保存的托管对象?

将对象从多个存储保存到单个持久存储

将 NSManagedObject(在主上下文中创建)从后台线程传递到主线程是不是安全?

Easyswoole 协程上下文管理 Context

cookie & session

cookie & session