Java 在Spring Security中的FORM_LOGIN_筛选器之后添加可选的身份验证步骤

Java 在Spring Security中的FORM_LOGIN_筛选器之后添加可选的身份验证步骤,java,spring,authentication,spring-security,Java,Spring,Authentication,Spring Security,我在Web应用程序中有一个基本的Spring Security登录工作流:用户通过一个表单登录,该表单最终由UserDetailsService中的应用程序逻辑处理,该服务由DaoAuthenticationProvider调用,使用UsernamePasswordAuthenticationFilter创建的令牌 然而,在某些情况下(通过用户偏好在运行时决定),我希望在这之后有一个额外的身份验证步骤(基本上是双因素身份验证)。我试着像这样添加另一个过滤器 <custom-filter r

我在Web应用程序中有一个基本的Spring Security登录工作流:用户通过一个表单登录,该表单最终由
UserDetailsService
中的应用程序逻辑处理,该服务由
DaoAuthenticationProvider
调用,使用
UsernamePasswordAuthenticationFilter
创建的令牌

然而,在某些情况下(通过用户偏好在运行时决定),我希望在这之后有一个额外的身份验证步骤(基本上是双因素身份验证)。我试着像这样添加另一个过滤器

<custom-filter ref="twoFactorAuthFilter" after="FORM_LOGIN_FILTER"/>

但如果表单登录成功,则永远不会调用此筛选器。我的计划是创建一个特殊的
TwoFactorAuthenticationToken
,它可以被
TwoFactorAuthenticationProvider
接受,但由于没有调用过滤器,我的新身份验证提供程序也不会被调用。如果登录凭据错误,我希望整个安全链中止,但如果正确,则继续遍历它并继续(可选)下一步


是否可以在不重写现有的
用户名密码身份验证筛选器的情况下按我的意愿执行此操作?我觉得这一定很容易,因为Spring通常是非常可扩展的,但我已经为此奋斗了很多天,还没有取得任何成功。

您只需要扩展
DAAuthenticationProvider
并覆盖
其他身份验证检查(UserDetails UserDetails,usernamepasswordauthenticationtokenauthentication)
使用您的登录后身份验证逻辑

public CustomDaoAuthenticationProvider extends DaoAuthenticationProvider {

    public additionalAuthenticationChecks(UserDetails userDetails,
        UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        super.additionalAuthenticationChecks(userDetails, authentication);

        // Your Logic Here
    }
}
编辑


我可能误解了你的问题,因为你提到了“逻辑”。无论如何,这显示了一个优雅的问题解决方案。

您想要的是有两个过滤器:一个用于
userNamePasswordFilter
,另一个用于
tokenFilter
。如果您的用户启用了双因素身份验证,则
daoAuthenticationProvider的
用户详细信息服务应该只授予他一个实例例如,使用角色“role\u PRE\u AUTH”的
SimpleGrantedAuthority
。对
tokenFilter
的访问权限应仅提供给具有此角色的用户-“role\u PRE\u AUTH”,并且该筛选器应尝试对您的辅助令牌进行身份验证,并继续授予用户其实际权限(用户、管理员等)从
tokenProvider

显示该附加弹出表单的方法是再次检查用户的角色是否为“role\u PRE\u AUTH”.

我如何以这种方式显示其他表单?我认为在身份验证提供程序中,必须在筛选级别执行此操作已经太晚了。但我不确定…这实际上与我最终执行的操作非常接近。是否显示其他对话框的决定是在
AuthenticationSuccessHandler
中完成的我认为,这仍然相当棘手。许多组件需要了解双因素身份验证,而我无法清楚地将其考虑在内。我使用
daoAuthenticationProvider
中的
AuthenticationSuccessHandler
ajaxSuccess
控制器端点重新使用,该端点在创建PIN令牌时发出201。然后,前端回调可以通过对登录表单进行适当更改来对此响应状态作出反应。