0

我有一个“鸡蛋”的问题。在应用程序中,我使用 UserDetailsS​​ervice 来获取用户(我们不在数据库中存储用户信息,我们使用第三方服务来实际获取所有信息)。

最近我们增加了帐户激活功能。注册后,我们会向用户发送一封激活电子邮件,如果他点击它,我们会将用户标记为 ACTIVE 并将他重定向到登录页面。用户只有在他有 ACTIVE 状态时才能登录。问题是:即使用户从未登录,我们也会从他激活帐户之日起开始向用户收费。我如何(可能使用弹簧安全)使这些过程(激活和登录)几乎同时进行?如果他只是激活他的帐户,我们不想向用户收费,我们只想在他登录后(激活后)才向他收费。所以我真的可以以某种方式做到这一点“用户单击激活链接,登录然后他的状态更改为 ACTIVE(但他只有在他是 ACTIVE 时才能登录)”。

抱歉,如果我的问题描述不够清楚

我会很感激任何反馈。

谢谢!

4

1 回答 1

0

如果我正确理解了您的要求,您的应用程序需要两个不同的入口点(登录页面):

  1. 一个用于尚未激活的用户的激活(首次登录)。
  2. 活跃用户的另一个“正常”。

问题是身份验证逻辑需要对上下文敏感,并了解上述哪个页面启动了身份验证。然而,该框架并不是为这种不常见的用例而设计的,因此身份验证提供者不知道实际发送登录表单的 URL。

您需要解决的是以某种方式将上下文信息传递给根据该信息处理身份验证请求的身份验证提供程序(即仅对从 url1 登录的非活动用户进行身份验证,并仅对从 url2登录的活动用户进行身份验证)。可能有数百种不同的方法来实现这一点,一种可能的解决方案是放置两个不同的身份验证过滤器来拦截发送到两个不同 URL 的身份验证请求。详情如下:

  1. 创建您自己的现有自定义版本,WebAuthenticationDetailsSource并且WebAuthenticationDetails(最好通过继承后者的子类)来存储和公开身份验证请求的 URI。(这将是身份验证提供者可以实现其条件逻辑的上下文信息。)
  2. UsernamePasswordAuthenticationFilter在过滤器链中配置并插入两个不同的实例。将它们的filterProcessesUrl属性分别设置为/j_spring_security_check_active_user/j_spring_security_check_nonactive_user,并在它们中注入上面创建的自定义AuthenticationDetailsSource
  3. DaoAuthenticationProvider.additionalAuthenticationChecks()通过以下方式 覆盖子类:
    • 检索存储在上面创建WebAuthenticationDetails的对象中的 URI(可以通过 访问authentication.getDetails()
    • 根据 URI 断言用户是活动/非活动的,AccountStatusException如果断言失败则抛出一个。
    • 如果断言成功,不要忘记委托给超类。
  4. 创建帖子开头提到的两个不同的登录页面,确保登录表单将凭据发布到各自的 URL ( /j_spring_security_check_nonactive_uservs. /j_spring_security_check_active_user)。
于 2013-04-16T23:57:41.030 回答