使用 Gmail 等 Spring Security 的两因素身份验证

Posted

技术标签:

【中文标题】使用 Gmail 等 Spring Security 的两因素身份验证【英文标题】:Two factor authentication with Spring Security like Gmail 【发布时间】:2014-04-12 09:01:51 【问题描述】:

在这里,我的场景有点类似于 Gmail 的两因素身份验证。当用户成功登录(SMS 代码发送给用户)时,他会被另一个页面挑战以输入 SMS 代码。如果用户正确获取 SMS 代码,他会看到受保护的页面(如 Gmail 收件箱)。

我对此进行了一些研究,suggestion 不是在登录时给 ROLE_USER,而是给他 PRE_AUTH_USER 并显示他输入 SMS 代码的第二页;成功后给他们ROLE_USER。

但是,我的问题是 Spring 有 InsufficientAuthenticationException,在这种情况下我们不会使用它。在我的场景中是否还有其他更好的方法来实现两因素身份验证?

附:我有一些定制的弹簧安全配置。在我的登录页面中,除了用户名和密码之外,我还有 Recaptcha 验证,还有我的 authenticationProviderm authenticationSuccessHandler、logoutSuccessHandler、accessDeniedHandler 都是自定义的。

【问题讨论】:

【参考方案1】:

短信验证码成功后,可以授予ROLE_USER权限,如下所示。

private void grantAuthority() 
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();


    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(auth.getAuthorities());
    authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
    Authentication newAuth =
        new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(),
            authorities);
    SecurityContextHolder.getContext().setAuthentication(newAuth);
  

代码是从blog post 和sample application 复制而来的,它实现了双因素身份验证。如果我早点找到它会节省很多时间!!!

【讨论】:

在哪里可以找到grantAuthority()? @罗伯特【参考方案2】:

如果第一级认证通过,尝试抛出InsufficientAuthenticationException,然后用ExceptionTranslationFilter抓住它并转发到第二级认证页面。

双因素认证页面可以重新提交隐藏字段中的用户名和密码,以及双因素令牌。在这第二次中,自定义身份验证提供程序将能够成功地对用户进行身份验证。

【讨论】:

将用户凭据写入隐藏字段是很糟糕的建议。 比在隐藏字段中存储凭据更好的方法是在第一阶段授权用户“PRE_AUTH”,而不是在第二阶段检查“PRE_AUTH”和代码。

以上是关于使用 Gmail 等 Spring Security 的两因素身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Spring 3.0 - 无法找到 XML 模式命名空间的 Spring NamespaceHandler [http://www.springframework.org/schema/securit

带有spring邮件发送的html邮件用gmail掩码

Spring Boot - 无法连接到 SMTP 主机:smtp.gmail.com,端口:25,响应:421

Spring通过Gmail SMTP服务器MailSender发送电子邮件

使用带有令牌的 spring 安全插件的一个好习惯

spring security