使用 Spring Security 3.2.x 进行两页登录

Posted

技术标签:

【中文标题】使用 Spring Security 3.2.x 进行两页登录【英文标题】:Two Page Login with Spring Security 3.2.x 【发布时间】:2014-01-18 18:28:31 【问题描述】:

我们对 Java、Spring 和 Spring Security 是全新的,但对开发并不陌生。我们已经能够创建一个基于 Spring Security 的 Thymeleaf 登录页面,该页面使用 JNDI 数据源使用 BCrypt 加密密码连接到我们的 SQL Server 数据库。所有这一切都在顺利进行。但是,客户端需要两阶段登录。第一个页面请求一个公司 ID,然后加载一个登录页面,其中包含该公司的特定图形和文本,这允许用户知道他们没有登录到网络钓鱼站点。然后该登录页面将请求用户名和密码。

我们在这里和整个网络上进行了广泛的搜索,但没有找到可靠的方法来做到这一点。我们认为我们可能不得不创建一个自定义的UserDetailsServiceAuthenticationManager,但仍然看不到如何实现它:

    用户无法绕过第一个登录屏幕直接进入第二个屏幕 SpringSecurity 控制两个页面

我们看到了一个关于将 Spring WebFlow 与 Spring Security 一起使用的建议,但没有一些起点,不知道 WebFlow 如何工作或应用于此场景。这个网站极大地帮助了我们进入这个阶段,但现在我们受到了阻碍。非常感谢您提供的任何帮助。

【问题讨论】:

要回答部分问题,在与自定义后端(不是普通的 LDAP 或 SS 管理的 JDBC)集成时,您通常需要创建一个 UserDetailsService。它基本上只是您的身份验证后端前面供 Spring Security 使用的外观,您只需使用 username 参数实现单方法接口即可执行所需的任何查找。 【参考方案1】:

我猜您的数据库将所有公司的所有用户都存储在一个表中。您不会将来自不同公司的用户分隔到不同的表中。如果是这种情况,您只需要一个登录页面。问题是,您有一个用户输入其公司 ID 的第一页,您使用此 ID 获取 JPG 和徽标并将它们放在登录页面上。

注意这并没有安全利益。因为任何人都可以输入其他公司的ID并获得不同公司的徽标,但仍然可以尝试登录。这是你的要求吗?

问题是您的登录页面需要根据之前输入公司 ID 的页面显示徽标和 JPG。如果没有给出,则显示错误。所以你的登录页面需要有一些逻辑和输入——如果你把它做成一个 JSP 就很容易实现......

HTH

【讨论】:

这基本上就是我们最终要做的。目前,初始登录屏幕请求 clientID 并从数据库中检索他们的信息。我们重载了用户登录页面,以将 clientID 作为其登录的一部分。从 Willie Wheeler 的回答中记下,我们建议在初始登录页面上加入一个验证码,如果该客户的系统不知道他们的 IP 地址,则该验证码会获取该客户的 ID。对于延迟将其标记为已回答,我们深表歉意,自从发布以来,我们一直在这个项目中深入了解。 谢谢!希望效果很好:-)顺便说一句-我很好奇:您是否实现了所有其他流程,例如“创建帐户”、“忘记密码”等? 是的。新用户帐户尚未到位,但所有忘记密码/用户名/客户端 ID、重置密码、密码规则等均已到位。 可惜没有“spring”项目 :-) 我为这些流程编写了一些通用代码......在 github 中。谢谢!【参考方案2】:

这里应该有三个页:

    初始登录页面的表单要求您输入用户名,但不输入密码。 你没有提到这个,但我会检查客户端计算机是否被识别,如果没有,然后用验证码或安全问题来挑战用户。否则网络钓鱼站点可以简单地使用提供的用户名向真实站点查询安全图像,这违背了拥有安全图像的目的。 (这里的安全问题可能会更好,因为使用 CAPTCHA 攻击者可以让人类坐在那里回答 CAPTCHA 以获取安全图像。这取决于你想变得多偏执。) 之后的页面显示安全图像并要求输入密码。

我认为这种简短的线性流不够复杂,无法保证使用 Spring Web Flow。

我将直接使用 Spring Web MVC 进行第 1 步和第 2 步。我不会将 Spring Security 用于初始登录表单,因为 Spring Security 的登录表单需要密码和登录处理 URL。同样,Spring Security 不提供对 CAPTCHA 或安全问题的特殊支持,因此您可以再次使用 Spring Web MVC。

您可以使用 Spring Security 处理第 3 步,因为现在您有了用户名和密码。表单登录页面应该显示安全图像,并且它应该包含用户提供的用户名作为隐藏的表单字段,以使 Spring Security 在用户提交登录表单时感到高兴。进入第 3 步的唯一方法是在第 1 步(和第 2 步,如果适用)上成功提交 POST

【讨论】:

好答案,但您似乎改变了他的要求:他希望第一页强制用户输入组织 ID,而不是他的用户名... 嗯,你是对的。虽然我想我没有看到在第二页上加载公司图形如何防止网络钓鱼,因为网络钓鱼站点可以使用相同的图形。我的回答解释了如何像金融网站那样实现两阶段登录。 我想这与您在回复中提出的观点相同。我同意你的看法。

以上是关于使用 Spring Security 3.2.x 进行两页登录的主要内容,如果未能解决你的问题,请参考以下文章

Spring CSRF 多部分文件上传

Spring Framework,Spring Security - 可以在没有 Spring Framework 的情况下使用 Spring Security?

仅使用 Spring-Security(或)Spring 进行授权

在使用 Oauth、SAML 和 spring-security 的多租户的情况下从 spring-security.xml 中获取错误

Spring security:Spring security 如何在 SessionRegistry 中注册新会话?

未调用 Spring Security j_spring_security_check