这是一个关于身份验证在 Spring 安全性中具有不同等级这一事实的概念性问题。
有一个等级
IS_AUTHENTICATED_ANONYMOUSLY
IS_AUTHENTICATED_REMEMBERED
IS_AUTHENTICATED_FULLY
在 AuthenticatedVoter#isFullyAuthenticated
的实现中很明显,完全认证的用户不能是 anonymous authenticated
或 remember-me authenticated
。
虽然我完全理解我们为什么要区分 IS_AUTHENTICATED_FULLY
和 IS_AUTHENTICATED_ANONYMOUSLY
,但我真的不明白为什么 IS_AUTHENTICATED_REMEMBERED
没有与 IS_AUTHENTICATED_FULLY
平等对待。
我理解记住我是使用某种秘密令牌进行身份验证 - 使用此令牌我们加载现有的 SecurityContext
,其中已经包含在初始 Authentication
期间写入的完全身份验证的 full authentication
对象.这方面基本恢复了全认证。
将其与具有类似令牌但在 Spring Security 中被视为完全身份验证的 session-login 相比,为什么记住我和基于会话之间存在差异?
考虑到remember-me 恢复了完全认证的SecurityContext
,应用程序逻辑会将上下文视为正常的完全认证。
如果我们对应用程序中的完全认证用户有一些逻辑,它肯定也适用于 remeber-me 认证的情况。
当然,对于 anonymous authenticated
的用户,我们经常需要做出不同的决定,所以这就是我理解为什么将其单独列出的原因。
我是否以错误的方式理解了“记住我”的概念,或者不将用户 remembered
视为完全通过身份验证的确切原因是什么?
答案 0 :(得分:1)
将其与具有类似令牌但在 Spring Security 中被视为完全身份验证的 session-login 相比,为什么记住我和基于会话之间存在差异?
通常,您的会话超时时间比记住我的令牌的生命周期要短。根据 Spring 的文档,remember-me 令牌的生命周期为 2 周,而会话超时通常以分钟为单位定义。
Remember-me 可以被认为类似于恢复超时的会话,但这与恢复安全上下文一样不安全。为什么?
通常,您希望应用多个安全层,并且您作为应用程序开发人员无法控制(至少不能直接控制)一些安全层,例如:
这基本上是“记住我”增加的第二个风险:如果用户正在积极使用应用程序,您只能假设用户仍在他们的机器前,因此您希望使会话超时尽可能短以快速确定用户处于非活动状态(并且足够长以保持良好的可用性水平)。
Remember-me 会重新激活一个不活动的会话(或至少是相关的安全上下文),因此在这里您假设现在在机器前面的用户是原始用户。无法保证这一点,因此记住我的身份验证可能被认为不太安全。
OAuth 刷新令牌可以被视为类似的东西:当用户成功通过身份验证时,您将获得一个访问令牌,但无论活动如何,访问令牌都会过期。然后,如果会话仍然处于活动状态,您将使用刷新令牌来获取新的访问令牌(这并不能保证用户发生了变化或没有发生变化)。
因此,在安全性和不考虑身份验证选项方面,我会按以下顺序对它们进行排名: