• SpringSecurity系列——记住我(remember me)day3-3(源于官网5.7.2版本)


    前言

    源于官方最新5.7.2文档,若你觉得官方文档阅读起来很枯燥,内容复杂,我提供了解析概括在每个部分的结尾,我对官方文档的内容做了一些改变,实例代码我会在后续进行更新,请查看如:SpringSecurity系列——认证架构实例代码的文章

    但是如果你有能力,还是推荐直接阅读官方文档

    remember me(记住我)

    记住我或持久登录身份验证是指网站能够记住会话之间主体的身份。 这通常是通过向浏览器发送 cookie 来完成的,该 cookie 在未来的会话中被检测到并导致自动登录发生。 Spring Security 为这些操作的发生提供了必要的钩子,并且有两个具体的 remember-me 实现。 一种使用散列来保护基于 cookie 的令牌的安全性,另一种使用数据库或其他持久存储机制来存储生成的令牌。

    请注意,这两种实现都需要一个 UserDetailsService. 如果您使用的身份验证提供程序不使用 UserDetailsService(例如,LDAP 提供程序)那么它将无法工作,除非您也有 UserDetailsService bean 在您的应用程序上下文中

    简单基于哈希的令牌方式

    这种方法使用散列来实现有用的记住我的策略。 本质上,在交互式身份验证成功后会向浏览器发送一个 cookie,该 cookie 的组成如下

    base64(username + ":" + expirationTime + ":" +
    md5Hex(username + ":" + expirationTime + ":" password + ":" + key))
    
    username:          As identifiable to the UserDetailsService
    password:          That matches the one in the retrieved UserDetails
    expirationTime:    The date and time when the remember-me token expires, expressed in milliseconds
    key:               A private key to prevent modification of the remember-me token
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    因此,remember-me 令牌仅在指定的时间段内有效,前提是用户名、密码和密钥不更改。 值得注意的是,这有一个潜在的安全问题,即在令牌过期之前,任何用户代理都可以使用捕获的记住我令牌。 这与摘要式身份验证的问题相同。 如果委托人知道令牌已被捕获,他们可以轻松更改密码并立即使所有已发布的记住我令牌无效。 如果需要更重要的安全性,您应该使用下一节中描述的方法。 或者,根本不应该使用记住我的服务。

    持久代币方法

    当前多数项目中并不建议采用这种方法

    原文地址

    记住我接口实现

    记住我与 UsernamePasswordAuthenticationFilter 一起使用,并通过 AbstractAuthenticationProcessingFilter 超类中的钩子实现。 它也在 BasicAuthenticationFilter 中使用。 这些钩子将在适当的时候调用一个具体的 RememberMeServices。 如下所示:

    Authentication autoLogin(HttpServletRequest request, HttpServletResponse response);
    
    void loginFail(HttpServletRequest request, HttpServletResponse response);
    
    void loginSuccess(HttpServletRequest request, HttpServletResponse response,
    	Authentication successfulAuthentication);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请注意 AbstractAuthenticationProcessingFilter 仅调用 loginFail() 和 loginSuccess() 方法。 每当 SecurityContextHolder 不包含 Authentication 时,都会由 RememberMeAuthenticationFilter 调用 autoLogin() 方法。 因此,该接口为底层的 remember-me 实现提供了足够的身份验证相关事件通知,并在候选 Web 请求可能包含 cookie 并希望被记住时委托给实现。 这种设计允许任意数量的记住我的实现策略。 我们在上面已经看到 Spring Security 提供了两种实现

    TokenBasedRememberMeServices

    此实现支持 Simple Hash-Based Token Approach 中描述的更简单的方法。 TokenBasedRememberMeServices 生成一个RememberMeAuthenticationToken,由RememberMeAuthenticationProvider 处理。 此身份验证提供程序和 TokenBasedRememberMeServices 之间共享一个密钥。 此外,TokenBasedRememberMeServices 需要一个 UserDetailsS​​ervice,它可以从中检索用户名和密码以进行签名比较,并生成 RememberMeAuthenticationToken 以包含正确的 GrantedAuthoritys。 如果用户请求,应用程序应提供某种注销命令,使 cookie 无效。 TokenBasedRememberMeServices 还实现了 Spring Security 的 LogoutHandler 接口,因此可以与 LogoutFilter 一起使用以自动清除 cookie。

    应用程序上下文中启用记住我服务所需的 bean 如下:

    <bean id="rememberMeFilter" class=
    "org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
    <property name="rememberMeServices" ref="rememberMeServices"/>
    <property name="authenticationManager" ref="theAuthenticationManager" />
    </bean>
    
    <bean id="rememberMeServices" class=
    "org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
    <property name="userDetailsService" ref="myUserDetailsService"/>
    <property name="key" value="springRocks"/>
    </bean>
    
    <bean id="rememberMeAuthenticationProvider" class=
    "org.springframework.security.authentication.RememberMeAuthenticationProvider">
    <property name="key" value="springRocks"/>
    </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    不要忘记将 RememberMeServices 实现添加到 UsernamePasswordAuthenticationFilter.setRememberMeServices() 属性中,将 RememberMeAuthenticationProvider 包含在 AuthenticationManager.setProviders() 列表中,并将 RememberMeAuthenticationFilter 添加到 FilterChainProxy(通常紧跟在 UsernamePasswordAuthenticationFilter 之后)。

    解释概括

    1. 记住我的业务存在安全风险,他人可以通过抓包得到凭证信息,借助进行伪造
    2. 记住我会和UsernamePasswordAuthenticationFilter和BasicAuthenticationFilter一起使用通过AbstractAuthenticationProcessingFilter 超类中的钩子在适当的时候调用一个具体的 RememberMeServices
  • 相关阅读:
    如何让你的.NET WebAPI程序支持HTTP3?
    SpringBoot自动配置
    发布自定义node包,实现自定义脚本命令
    鸿蒙ArkUI-X跨端应用开发,一套代码构建多平台应用
    形态学 - 凸壳
    代码随想录 Day40 动态规划08 LeetCodeT198打家劫舍 T213打家劫舍II T337 打家劫舍III
    K8S java应用jvm内存诊断解决方案:java应用诊断和在线debug利器bistoury介绍及在K8S环境中的使用
    基于SpringBoot+Vue实现的党校培训管理系统源代码+数据库
    解决IDEA下载mysql驱动太慢
    机器人操作系统ROS(22)ROS安装opencv
  • 原文地址:https://blog.csdn.net/qq_51553982/article/details/125902303