【问题标题】:Why is remember-me a lesser authentication then full-authentication in spring-security?为什么在 spring-security 中,remember-me 的身份验证比完全身份验证要少?
【发布时间】:2021-09-12 11:04:59
【问题描述】:

这是一个概念性问题,即身份验证在 Spring Security 中具有不同的等级。

有一个等级

  1. anonymous authentication 也称为 IS_AUTHENTICATED_ANONYMOUSLY
  2. remember me authenticationIS_AUTHENTICATED_REMEMBERED
  3. 完整的身份验证,当用户提供他的全部凭据并得到确认时,又名IS_AUTHENTICATED_FULLY

AuthenticatedVoter#isFullyAuthenticated 的实现中,很明显,完全认证的用户不能是anonymous authenticatedremember-me authenticated

虽然我完全理解为什么要区分 IS_AUTHENTICATED_FULLYIS_AUTHENTICATED_ANONYMOUSLY,但我真的不明白为什么 IS_AUTHENTICATED_REMEMBERED 没有与 IS_AUTHENTICATED_FULLY 同等对待。

我怎么理解记得我:

我知道记住我是使用某种秘密令牌进行身份验证 - 使用此令牌,我们加载现有的 SecurityContext,其中已经包含在初始 full authentication 期间写入的完全身份验证的 Authentication 对象。这方面基本恢复了全鉴权。

与 session-login 相比,它具有类似的令牌,但在 Spring Security 中被认为是完全身份验证,为什么记住我和基于会话之间存在差异?

问题:

考虑到 remember-me 恢复了经过全面验证的 SecurityContext,应用程序逻辑会将上下文视为正常的完整身份验证。

如果我们对应用程序中的完全认证用户有一些逻辑,它肯定也适用于记住我认证的情况。

当然,对于anonymous authenticated 用户,我们经常需要做出不同的决定,所以这就是我理解为什么要挑出来的原因。

我是否以错误的方式理解记住我的概念,或者没有将用户 remembered 视为完全经过身份验证的确切原因是什么?

【问题讨论】:

  • 如果使用“记住我”,您将面临其他人无需提供凭据即可访问该应用程序的风险,而且这种情况在未经原始用户同意或不知情的情况下发生。因此,这应该被视为较低级别的身份验证:您知道用户在某个时候成功登录,但您不知道返回会话的用户仍然是该用户。
  • 以这种方式窃取会话与窃取密码一样困难(大多数情况下)。我们需要以某种方式获得一个秘密,即会话令牌,并提供它来获得身份验证。这就像 PAT,不是吗?拥有基于会话的身份验证将是 Spring Boot 中常见的事情之一。在查看安全上下文时,我无法想象这两个(完整/记住我)之间的实际后端逻辑在内部会有什么不同。这个标记是否只是在 spring-secuirty 过滤器链中要知道的(并采取行动) - 但是那两个是相同的(相同的 SecurityContext)?
  • 这可能取决于您的观点,但记住并因此恢复会话之间有一段时间不活动会冒用户成为不同人的风险。这不是窃取会话,而是其他人访问用户计算机。您可能会争辩说操作系统会话也应该被锁定,但作为应用程序提供商,您不能也不应该依赖这种情况。如果您真的想将记住的会话与完全验证的会话一样对待,您应该仍然可以这样做,但这将是您的选择和责任。
  • 另请注意,应用程序通常需要已通过身份验证的用户重新对关键操作进行身份验证,原因相同:即使会话仍然处于活动状态,也不能保证机器前面的人仍然是登录或该人离开并忘记锁定屏幕的那个人。
  • 其他人访问计算机也可能滥用用户名/密码,对吗?或者您是否指出 session-id 纯粹是由属性和用户名/密码(当没有写在计算机上时)是由知识,因此后者被认为是保存?如果我会有所不同,我的意思是要知道更长的时间允许基于会话的登录,或者正如您发布的那样,在“一段时间后”(30 分钟)对用户进行某种重新身份验证/验证。你和这里的会议有什么不同吗?意味着,会话有一个到期(和一个令牌),是记住我..

标签: java spring-security spring-session spring-security-rest


【解决方案1】:

与 session-login 相比,它具有类似的令牌,但在 Spring Security 中被认为是完全身份验证,为什么记住我和基于会话之间存在差异?

通常,您的会话超时时间比记住我令牌的生命周期要短。根据 Spring 的文档,remember-me 令牌的生命周期为 2 周,而会话超时通常以分钟为单位定义。

Remember-me 可以被认为类似于恢复超时的会话,但这与恢复安全上下文一样不安全。为什么?

一般来说,您希望应用多个安全层,而您作为应用程序开发人员无法控制(至少不是直接),例如:

  • 无法保证用户不会共享其凭据(用户名/密码),因此可能需要进行多重身份验证。
  • 无法保证经过身份验证的用户离开他们的计算机并且不会锁定它。在这种情况下,其他人可以访问该应用程序,因此您希望令牌的寿命尽可能短。因此,许多应用程序使用额外的令牌进行关键操作,例如当我可以在亚马逊上将产品放入我的购物车时,但当我想下订单时,我需要重新验证以确保它确实是我。

这基本上是记住我增加的第二个风险:如果用户正在积极使用应用程序,您只能假设用户仍在他们的机器前,因此您希望尽可能短地缩短会话超时时间确定用户处于非活动状态(并且寿命足够长以保持良好的可用性水平)。

Remember-me 会重新激活一个非活动会话(或至少是相关的安全上下文),因此您在这里假设现在在机器前面的用户是原始用户。无法保证这一点,因此记住我的身份验证可能被认为不太安全。

OAuth 刷新令牌可以被视为类似的东西:当用户成功通过身份验证时,您会获得一个访问令牌,但无论活动如何,访问令牌都会过期。然后,如果会话仍处于活动状态(不能保证用户改变或没有改变),您将使用刷新令牌获取新的访问令牌。

因此,就安全性而言,不考虑身份验证选项,我将按以下顺序对它们进行排名:

  • access token 通过显式验证用户来检索:将其用于关键操作,使其短暂存在,并且不为这些操作提供刷新令牌
  • refresh token 和通过刷新令牌检索的访问令牌:基本上与会话安全性相当,因为刷新令牌的寿命通常与会话寿命有关(如果用户在时间 X 内未访问受保护的资源,则访问令牌和刷新令牌会过期,用户需要重新认证)。请注意,刷新令牌不应与用户共享。
  • remember-me 令牌:可被视为与用户共享的长期刷新令牌形式

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-27
    • 2022-01-15
    • 2014-02-26
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2016-11-11
    • 2015-01-08
    相关资源
    最近更新 更多