这是一个奇怪的问题,但我可以 100% 地重现它。
根据使用 Grails Spring Security 自动登录,推荐的以编程方式登录用户的方法是使用 springSecurityService.reauthenticate(username),这在注册确认后在 Spring-Security-UI 插件中使用。
但是我的应用程序有这种非常奇怪的行为,它似乎没有立即生效(我尝试立即重定向到经过身份验证的页面),但前提是之前没有从该浏览器在我的域上进行过登录尝试。注意我在我的代码和 spring-security-ui '验证注册'中都看到了这种行为,它使用这种方法来登录用户。
为了澄清,如果我:
- 清除 my.domain.com 的 JSESSIONID cookie(我的 grails 应用程序在这里运行,但我也可以在 localhost 上重现)
- 点击控制器输入用户ID,提交时应自动登录用户,然后将他们重定向到他们需要登录的页面
- 我最终不是在页面上,而是被踢到登录屏幕(如果您尝试在没有身份验证的情况下访问该页面,就会发生这种情况)。请注意 URL 上的 jsessionid(当然它每次都会更改),我没有把它放在那里。https://my.domain.com/login/auth;jsessionid=B1C9A849E222476A9C9987923D439D13
- 请注意,这似乎不是我在登录生效之前重定向的竞争条件,就好像我尝试手动进入经过身份验证的页面一样,它仍然失败。我只是没有登录。
注意在步骤 2 中点击控制器,或任何其他控制器实际上确实会立即给我一个 JSESSIONID,其值与 URL 上的值不同。
但是,如果我:
- 确保我有一个来自先前登录尝试的 JSESSIONID cookie,无论成功与否。确保我已注销。
- 从上面重复步骤 2(对于任何用户,而不是第一次尝试的用户)
- 一切都按预期工作!我已成功登录并在需要身份验证的页面上。在我再次清除该 cookie 之前,它将继续为任何未来的尝试工作。
我很困惑。不知何故,我得到了冲突的 JSESSIONID 值。在调用 springSecurityService.reauthenticate(username) 之后但在调用 redirect(...securepage...) 之前是否需要做其他事情。请注意,我确实使用了通道安全性,它在整个重定向过程中在 http 和 https 之间反弹 - 但我不确定这与仅在之前进行过一次身份验证尝试时才工作的奇怪行为有何关系。
请注意,通过登录屏幕使用用户名和密码进行的正常登录首次使用干净的 cookie。