如果我正确理解了您的要求,您的应用程序需要两个不同的入口点(登录页面):
- 一个用于尚未激活的用户的激活(首次登录)。
- 活跃用户的另一个“正常”。
问题是身份验证逻辑需要对上下文敏感,并了解上述哪个页面启动了身份验证。然而,该框架并不是为这种不常见的用例而设计的,因此身份验证提供者不知道实际发送登录表单的 URL。
您需要解决的是以某种方式将上下文信息传递给根据该信息处理身份验证请求的身份验证提供程序(即仅对从 url1 登录的非活动用户进行身份验证,并仅对从 url2登录的活动用户进行身份验证)。可能有数百种不同的方法来实现这一点,一种可能的解决方案是放置两个不同的身份验证过滤器来拦截发送到两个不同 URL 的身份验证请求。详情如下:
- 创建您自己的现有自定义版本,
WebAuthenticationDetailsSource
并且WebAuthenticationDetails
(最好通过继承后者的子类)来存储和公开身份验证请求的 URI。(这将是身份验证提供者可以实现其条件逻辑的上下文信息。)
UsernamePasswordAuthenticationFilter
在过滤器链中配置并插入两个不同的实例。将它们的filterProcessesUrl
属性分别设置为/j_spring_security_check_active_user
和/j_spring_security_check_nonactive_user
,并在它们中注入上面创建的自定义AuthenticationDetailsSource
。
DaoAuthenticationProvider.additionalAuthenticationChecks()
通过以下方式
覆盖子类:
- 检索存储在上面创建
WebAuthenticationDetails
的对象中的 URI(可以通过 访问authentication.getDetails()
)
- 根据 URI 断言用户是活动/非活动的,
AccountStatusException
如果断言失败则抛出一个。
- 如果断言成功,不要忘记委托给超类。
- 创建帖子开头提到的两个不同的登录页面,确保登录表单将凭据发布到各自的 URL (
/j_spring_security_check_nonactive_user
vs. /j_spring_security_check_active_user
)。