【发布时间】:2021-09-12 11:04:59
【问题描述】:
这是一个概念性问题,即身份验证在 Spring Security 中具有不同的等级。
有一个等级
-
anonymous authentication 也称为
IS_AUTHENTICATED_ANONYMOUSLY - 和remember me authentication
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,其中已经包含在初始 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