Spring Security 的记住我功能
问题是:
我们必须实施两步登录过程。第一步 - 用户输入名称/密码并进行身份验证。第二步-用户可能会看到辅助选择屏幕,他可以通过简单的点击来选择一个选项。完成此操作后,用户最终被授权执行某些操作。当前用户会话的身份验证/授权过程到此结束。
我们确实以标准形式使用 Spring Security:第一个登录屏幕由默认的 Spring Security 堆栈处理,一旦用户进入,Spring 就会认为登录过程已完成。
辅助选择屏幕完全在 Spring Security 之外,我们在用户选择时所做的就是将正确配置的对象设置回安全上下文。这按预期适用于当前会话。
我们也有记住我的功能,这是通过第一个登录屏幕中名为 _spring_security_remember_me 的复选框以及重写的 UserDetailsService bean 实现的。
只要没有辅助选择屏幕选项,“记住我”功能就可以正常工作。由于辅助屏幕与 Spring Security 无关,因此辅助选项不会激活记住我机制,它所能做的就是仅记住第一个登录步骤。这导致必须询问记住的用户该选项,我们的任务是避免这种情况。
在同一页面上同时提供登录表单和辅助选择并不是一种选择。
如果需要二次选择,我们可以使用额外的 cookie,并在身份验证时基于该 cookie“静默”传递所需的参数。但这意味着我们必须做 Spring Security“应该”提供的大量手动操作,这也将一些安全逻辑和令牌置于 Spring 管理的安全性和记住我功能之外。
因此,安全专家面临的问题是:如何“强制”记住我功能接受第二个呈现的选项?如果 Remember-Me 过滤器可以“检查”传递的 URL 并确定选择了 Remember-me 选项,那么我们可以添加此参数。但这听起来不太可能。
是否可以/可行在辅助屏幕上使用另一个登录表单并“默默地”传递只需要的附加参数?我知道在这种情况下我们不会包含用户名/密码,至少不会以明确的形式包含。该选项听起来像是可以完成的,但我仍然相信可能有一种更简单的方法来强制“记住我”做它所做的事情。或者有吗?
谢谢, 尼古拉
Here is the issue:
We have to implement two-step login process. First step - user enters name/password and is being authenticated. Second step - user may be presented with secondary select screen where he chooses an option via simple click. When this is done user is finally authorized for certain set of actions. This concludes authentication/authorization process for current user session.
We do use Spring Security in its standard form: first login screen is handled by default Spring Security stack and as soon as user is in - Spring considers the login process done.
The secondary selection screen is completely outside of Spring Security and all we do upon user selection is set the properly configured object back into security context. This works for current session as expected.
We do have remember-me functionality as well which is implemented via checkbox named _spring_security_remember_me in the first login screen and also an overridden UserDetailsService bean.
The remember-me works fine for as long as there is no secondary select screen option. Since the secondary screen has nothing to do with Spring Security, the remember-me mechanism would not be activated for secondary option and all it is capable of is to remember only the first login step. This results with having to ask remembered user the option and we are tasked to avoid this.
Having both login form and secondary selection on the same page is not an option.
We could use additional cookie if the secondary selection is required and based on that cookie "silently" pass the needed parameter when authenticating. But this would mean that we have to do bunch of manual stuff which Spring Security "ought" to offer, also this puts some security logic and tokens outside of Spring managed security and remember-me functionality.
So here is the question to security gurus: how to "force" remember-me functionality to accept the secondary presented option? If it was possible for Remember-Me filter to "inspect" the passed URL and identify that remember-me option is chosen, we could add this parameter. But this does not sound like it is possible.
Is it possible/feasible to use yet another login form on secondary screen and "silently" pass just needed additional parameters? I know we won't include the user name/password in this case, at least not in clear form. The option sounds like it can be done, but I am still believing that there might be an easier way to just force the Remember-Me to do what it does. Or is there?
Thanks,
Nikolay
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以将每个用户最后选择的选项存储在数据库中。然后你实现一个 AuthenticationSuccessHandler 从数据库读取存储的选项并将其设置在安全上下文中。如果未找到该选项,用户将被重定向到选择屏幕。
仅当您使用 Spring Security 3.1 或更高版本时,无论身份验证类型(表单、基本或记住)如何,这都应该有效,因为已经引入了注册 AuthenticationSuccessHandler 的可能性 该版本。 Spring 论坛中有一个关于此主题的讨论。
You could store the last selected option for each user in the database. Then you implement an AuthenticationSuccessHandler that reads the stored option from the database and sets it in the security context. If the option is not found, the user is redirected to the selection screen.
This should work regardless of the authentication type (form, basic or remember-be) only if you are using Spring Security 3.1 or later, as the possibility to register an AuthenticationSuccessHandler has been introduced in that version. There's a discussion on this topic in the Spring Forums.