Spring 社交登录和 Spring Security 自定义身份验证管理器

Posted

技术标签:

【中文标题】Spring 社交登录和 Spring Security 自定义身份验证管理器【英文标题】:Spring social signin and spring security custom authentication manager 【发布时间】:2013-01-10 19:26:54 【问题描述】:

我正在尝试了解我是否正确处理了我的服务器身份验证

我正在创建一个使用 Facebook 自动登录的服务器,另外我正在使用休眠

我通过与默认 JdbcUsersConnectionRepository 相同的过程来做到这一点 但我总是返回一个用户。如果没有找到。

@Override
public List<String> findUserIdsWithConnection(Connection<?> connection) 
    List<String> ret = new LinkedList<String>();
    ConnectionKey key = connection.getKey();
    MyUser myUser = userService.getUserBySocialConnection(key.getProviderId(), key.getProviderUserId());
    if (myUser == null)
    
        MyUser user = userService.createUserFromConnection(connection);
        String myUserId = String.valueOf(user.getId());
        ret.add(myUserId);
    else
    
        ret.add(String.valueOf(myUser.getId()));
    
    return ret;

所以我的signIn 有这个代码。登录用户:

   public String signIn(String userId, Connection<?> connection, NativeWebRequest request) 
    MyUser user = userService.getUserById(Long.parseLong(userId));
    Authentication authentication = SecurityToolbox.signInUser(user);
    // set remember-me cookie
    MyUser myu = (MyUser)authentication.getPrincipal();
    userCookieGenerator.addCookie(String.valueOf(myu.getId()), request.getNativeResponse(HttpServletResponse.class));
    return null;

以及来自SecurityToolBox 的登录代码:

  public static Authentication signInUser(MyUser user) 
    List<GrantedAuthority> authorities = getAuthorities(user);
    Authentication authentication = new UsernamePasswordAuthenticationToken(user, "", authorities);
    SecurityContextHolder.getContext().setAuthentication(authentication);
    return authentication;
  

现在所有这一切都由我编写的userInterceptor 处理,它处理读取cookie(如果可用)并记住用户(如果存在)。 我现在可以通过 cookie 发送给用户以记住我的最佳保护信息是什么?我正在发送用户 ID,但这不是我想要的

我现在想让 Spring Security 处理我的会话/remmeberme/身份验证过程 但我真的不明白我应该做什么。

第一个问题 在下一个请求中,我的代码是否足以通过服务器正确验证用户身份?如果我在userInterceptor 中询问SecurityContextHolder.getContext().getAuthentication() != null 是否可以安全地假设用户已登录?

现在我希望使用 spring security 来处理我的身份验证,而不是自己使用拦截器进行身份验证。所以我想创建一个身份验证管理器。但我不明白我需要在

中进行身份验证
        public class CustomAuthenticationManager implements AuthenticationManager 
public Authentication authenticate(Authentication auth)
        throws AuthenticationException 

我没有用户名和密码,我只是通过 facebook 验证登录,所以我用什么验证。 总的来说,我在这里有一些知识差距,我真的不明白我应该怎么做才能让所有东西都粘在一起

第二个问题 对于我的情况,authenticate 函数究竟需要发生什么

第三个问题 我希望 Spring Security 处理会话和 cookie 以记住我。我知道有一个与 u/p 令牌相同的记住我令牌,但我仍然不明白我应该如何在我的情况下使用它。

第四个问题 现在,发送到服务器的每个请求(不是资源)都会发生整个登录过程。这就是它应该发生的方式吗?

谢谢。

【问题讨论】:

【参考方案1】:

那里有很多问题。首先,您在第一个框中编写的代码实际上已经通过可以注入的 ConnectionSignUp 在 JdbcUsersConnectionRepository 中得到支持。 ConnectionSignUp 是一个策略接口,如果 JdbcUsersConnectionRepository 找不到用户,您可以实现该接口来创建用户。查看 spring-social-quickstart 应用程序以查看实际示例。

如果不深入阅读,您的登录代码看起来还不错,但我同意从本质上重新创建 Spring Security 在拦截器中已经完成的所有工作需要大量工作。出于这个原因,Spring Social 的最新快照构建包括与 Spring Security 更紧密的集成。

新的东西有一个 SocialAuthenticationFilter,它是一个 Spring Security 身份验证过滤器,就像任何其他身份验证过滤器一样,它直接插入 Spring Security 的过滤器链。此身份验证过滤器通过将用户的提供者信息与本地应用程序上先前建立的连接进行比较来工作,并在找到匹配项时将其登录。否则,它会重定向到注册页面。

从功能的角度来看,它的工作与 Spring Social 的 ProviderSignInController 相同。但是,它的不同之处在于它与 Spring Security 非常紧密地集成在一起,因此您期望的所有安全性东西(记住我、权限等)都可以按照您的预期工作,而无需太多/任何额外的努力部分。

同样,这仅在最新的 1.1.0.BUILD-SNAPSHOT 版本中,但我预计(除非有任何意外)会在下周初推出 1.1.0.M2 版本。如果您想查看一些实际示例,请查看 spring-social-showcase-sec 或 spring-social-showcase-sec-xml 示例。

【讨论】:

以上是关于Spring 社交登录和 Spring Security 自定义身份验证管理器的主要内容,如果未能解决你的问题,请参考以下文章

社交登录,spring-security-oauth2 和 spring-security-jwt?

Spring Boot 和 OAuth2 社交登录,无法获取 refreshToken

如何使用 Angular 和 Spring Boot 添加社交登录功能

为社交登录用户生成不记名令牌 Spring Boot

如何使用 OAuth2 和社交登录保护 Spring Boot RESTful 服务

Spring Boot 社交登录和本地 OAuth2-Server