登录亚马逊的春季安全

时间:2016-05-30 06:37:21

标签: spring-security facebook-login spring-security-oauth2

我们有一个使用基本身份验证(用户和密码)的应用程序,我们在数据库中创建了角色,它完美地运行。 现在我们正在迁移使用Login With Amazon,我们还将添加Login with Facebook。 是否有一种简单的方法来保持我们当前的Spring Security架构(我不再需要用户密码,我想保留角色)并添加对使用Amazon登录的支持。

我注意到有关于Spring Security的这个项目有oAuth2 http://projects.spring.io/spring-security-oauth/我不清楚这是做什么的。

1 个答案:

答案 0 :(得分:0)

Spring oAuth的文档非常糟糕,但如果您了解Spring Security的方法,那么它们提供的examples是可行的。

我想在此标记使用oAuth 2进行用户身份验证isn't recommended,并且您应该坚持使用支持Open ID Connect的提供程序。我很快就会看到登录亚马逊,如果它是OIDC或只是简单的oAuth2,但无论哪种方式,你都可以使用他们的SDK来实现你想要的东西。

绝对可以使用Spring oAuth来设置oAuth 2的登录,也可能是OIDC,但我总是最终推出自己的解决方案,因为我发现它更简单。

我将专注于在亚马逊登录,但使用Facebook登录应该非常相似。

您需要做四件事:

  1. 将亚马逊登录添加到您的网站
  2. 实施对在用户个人资料中存储用户外部ID的支持
  3. 实施用于处理JWT令牌和“登录”用户
  4. 的控制器
  5. 用户登录后调用新控制器
  6. 第一个应该相当容易,详见Amazon's documentation

    第二个完全取决于您,因为它取决于您的数据库解决方案,但如果您将自己局限于一个或两个提供商,最简单的方法可能是只添加属性 amazonId 用户个人资料。

    第三个看起来像这样:

    @Controller
    public class OidcController {
    
        @Autowired
        private ObjectMapper objectMapper;
    
        @RequestMapping("/login/amazon")
        public String handleAmazonOidc(@RequestParam String access_token) {
            // verify that the access token belongs to us
            Content c = Request.Get("https://api.amazon.com/auth/o2/tokeninfo?access_token=" + URLEncoder.encode(access_token, "UTF-8"))
                           .execute()
                           .returnContent();
    
            Map<String, Object> m = (Map<String, Object>)objectMapper.readValue(c.toString(), Map.class);
            if (!"YOUR-CLIENT-ID".equals(m.get("aud"))) {
                // the access token does not belong to us
                throw new InvalidTokenException("Invalid token");
            }
    
            // Get the user ID from Amazon and get the corresponding user on our end
            m = new ObjectMapper().readValue(c.toString(), new TypeReference>(){});
            String amazonUserId = m.get("user_id");
    
            User user = getUserFromAmazonId(amazonUserId);
            if (user == null) {
                // User needs to register first
                return "redirect:/register";
            }
    
            // Authenticate the user in the current security context
            PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(user, token, user.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(token);
    
            // Redirect the user to the front page
            return "redirect:/";
        }
    }
    

    第四个很简单,只需在UI中的回调中重定向用户:

    amazon.Login.authorize(options, 'https://www.example.com/login/amazon');
    

    现在,您遇到了一些麻烦,因为您已经在数据库中找到了没有要查找的Amazon用户ID的用户,因此您可能需要并行运行这两种身份验证方案允许用户在使用用户名和密码登录时与亚马逊联系。修改上述控制器以在当前用户配置文件中插入Amazon用户ID而不是在安全上下文中设置它应该是相当简单的。