首页 > 其他分享 >security状态切换

security状态切换

时间:2025-01-13 23:44:35浏览次数:1  
标签:状态 用户 对象 UsernamePasswordAuthenticationToken 认证 Authentication 切换 security true

在 Spring Security 中,"未认证" 到 "已认证" 的转换是通过 Authentication 对象的状态变化 来实现的。以下是具体的实现原理和步骤:


1. 核心原理

  • "未认证":最初,Authentication 对象中没有认证成功的标志,例如用户凭据(用户名和密码)仅供验证使用。
  • "已认证":一旦验证成功,会创建一个新的 Authentication 对象,标记为已认证(isAuthenticated = true),并且这个对象中包含用户的详细信息、权限信息等。

Spring Security 通过 AuthenticationManagerProvider 的协作来完成这个状态切换,核心在于构造和返回一个已认证的 Authentication 对象。


2. 实现步骤

UsernamePasswordAuthenticationToken 为例,整个流程如下:

(1) 未认证对象的创建

过滤器(如 UsernamePasswordAuthenticationFilter)会将用户的输入(用户名和密码)封装成一个 "未认证" 的 Authentication 对象:

java // 用户输入的用户名和密码 String username = ...; String password = ...; // 构建一个未认证的 Authentication 对象 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);

此时:

  • principal = 用户名(如字符串 "user")。
  • credentials = 密码(如字符串 "password")。
  • authorities = null,因为还未认证。

(2) 传递给 AuthenticationManager

这个未认证的 Authentication 对象会被传递给 AuthenticationManager,由其负责认证。

java Authentication result = authenticationManager.authenticate(authentication);

(3) 由 Provider 验证用户信息

  • AuthenticationManager 会将 Authentication 对象传递给合适的 AuthenticationProvider
  • 具体的 Provider(如 DaoAuthenticationProvider)会通过 UserDetailsService 加载用户信息,并对密码进行校验。

关键代码示例:

java @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 1. 从 Authentication 中获取用户凭据 String username = authentication.getName(); String password = authentication.getCredentials().toString(); // 2. 从数据库加载用户 UserDetails userDetails = userDetailsService.loadUserByUsername(username); // 3. 校验密码 if (!passwordEncoder.matches(password, userDetails.getPassword())) { throw new BadCredentialsException("Invalid username or password"); } // 4. 返回已认证的 Authentication 对象 return new UsernamePasswordAuthenticationToken( userDetails, null, // 密码可以不再存储 userDetails.getAuthorities() // 用户权限 ); }

(4) 创建一个新的、已认证的 Authentication 对象

  • 校验成功后,Provider 会返回一个新的 UsernamePasswordAuthenticationToken 对象。
  • 这个对象中:
    • principal = UserDetails 对象,包含用户的详细信息。
    • credentials = 通常设置为 null,因为密码已经校验通过,不需要再保存。
    • authorities = 用户的权限列表,供后续授权使用。
    • isAuthenticated = true,标记为已认证。

(5) 存储到 SecurityContext 中

  • 最后,过滤器会将新的 Authentication 对象存储到 SecurityContextHolder 中,标志用户已认证。
  • 核心代码:
java SecurityContextHolder.getContext().setAuthentication(authentication);

3. "未认证" 到 "已认证" 的具体对比

属性未认证状态已认证状态
principal 用户名(如字符串 "user") 用户详细信息(UserDetails 对象)
credentials 用户输入的密码 通常为 null,因为密码已校验成功,不再需要存储
authorities null 用户的权限列表(从 UserDetails 中提取)
isAuthenticated() false true,表示认证通过
存储位置 仅存在于过滤器的临时变量中 存储在 SecurityContextHolder 中,供后续使用

4. 为什么要返回一个新的 Authentication 对象?

  1. 状态的区分

    • "未认证" 和 "已认证" 是两种状态,直接标记在 Authentication 对象上。
    • Spring Security 的设计中,Authentication 对象是不可变的,因此要返回一个新的对象表示状态的改变。
  2. 安全性

    • 未认证的对象可能存储着用户的敏感数据(如明文密码)。
    • 返回新的对象时,可以将密码设置为 null
   
您说:
isAuthenticated = true 这个是默认就是true还是怎么说,AuthenticationManager 又怎么感知对象对象切换的  
ChatGPT 说:
ChatGPT

1. isAuthenticated = true 是默认的吗?

不是默认的,isAuthenticated 的值是由 Authentication 对象的设计逻辑决定的,具体可以分为以下几种情况:

  • 在 "未认证" 的状态下:

    • 当你手动创建一个 Authentication 对象(如 UsernamePasswordAuthenticationToken)时,默认的 isAuthenticated 值是 false,表示对象尚未认证。
    • 例如: java UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); System.out.println(token.isAuthenticated()); // 输出 false
  • 在认证通过后:

    • 如果认证成功,Spring Security 通常会返回一个新的 Authentication 对象(如 UsernamePasswordAuthenticationToken),并将其 isAuthenticated 设置为 true
    • 设置为 true 的动作通常是在代码中明确完成的。例如: java UsernamePasswordAuthenticationToken authenticatedToken = new UsernamePasswordAuthenticationToken(userDetails, null, authorities); authenticatedToken.setAuthenticated(true); // 明确标记为已认

标签:状态,用户,对象,UsernamePasswordAuthenticationToken,认证,Authentication,切换,security,true
From: https://www.cnblogs.com/zyb-luckey/p/18669631

相关文章

  • 股票异动拉升中间过程状态分析和检测算法
    一.股票异动拉升中间过程状态分析和检测算法将股票分为:空闲,开始,持续,快停,涨停五种状态:可以勾选的方式来筛选处于五种状态的股票,更加精准的找出开始拉升,持续拉升,快要涨停的股票,对于处于空闲状态或者已经涨停的股票可以先不关注。   添加图片注释,不超过1......
  • HTTP常见状态码:从1xx到 5xx的全面解析
    在网络世界中,浏览网页、发送请求、调用接口几乎无处不在,但你是否注意过这些操作背后返回的状态码?它们就像网络的“语言”,通过简单的数字告诉我们操作成功与否、问题出在哪里,以及接下来该如何处理。今天,让我们全面解析HTTP常见状态码,从1xx到5xx,帮你读懂网络的秘密!什么是H......
  • LampSecurityCTF4---靶机练习
    LampSecurityCTF4靶机练习声明B站UP主泷羽sec笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。✍......
  • 别再“硬扛”了!稳定性保障主导权切换硬核指南:运维 or QA,何时“换帅”才能止损?
    相信不少朋友都有过这样的经历:线上告警突如其来,团队成员立刻紧张起来,争分夺秒地排查问题、快速止损。在稳定性保障这条道路上,谁来主导,至关重要。我曾身处美团金融团队,深知在应对大流量冲击、快速止损方面的运维主导模式的威力。那种对系统运行状态的精准把握,对预案执行的果断高效......
  • 别再“硬扛”了!稳定性保障主导权切换硬核指南:运维 or QA,何时“换帅”才能止损?
    相信不少朋友都有过这样的经历:线上告警突如其来,团队成员立刻紧张起来,争分夺秒地排查问题、快速止损。在稳定性保障这条道路上,谁来主导,至关重要。我曾身处美团金融团队,深知在应对大流量冲击、快速止损方面的运维主导模式的威力。那种对系统运行状态的精准把握,对预案执行的果断高效......
  • 别再“硬扛”了!稳定性保障主导权切换硬核指南:运维 or QA,何时“换帅”才能止损?
    相信不少朋友都有过这样的经历:线上告警突如其来,团队成员立刻紧张起来,争分夺秒地排查问题、快速止损。在稳定性保障这条道路上,谁来主导,至关重要。我曾身处美团金融团队,深知在应对大流量冲击、快速止损方面的运维主导模式的威力。那种对系统运行状态的精准把握,对预案执行的果断高效......
  • 别再“硬扛”了!稳定性保障主导权切换硬核指南:运维 or QA,何时“换帅”才能止损?
    相信不少朋友都有过这样的经历:线上告警突如其来,团队成员立刻紧张起来,争分夺秒地排查问题、快速止损。在稳定性保障这条道路上,谁来主导,至关重要。我曾身处美团金融团队,深知在应对大流量冲击、快速止损方面的运维主导模式的威力。那种对系统运行状态的精准把握,对预案执行的果断高效......
  • 别再“硬扛”了!稳定性保障主导权切换硬核指南:运维 or QA,何时“换帅”才能止损?
    相信不少朋友都有过这样的经历:线上告警突如其来,团队成员立刻紧张起来,争分夺秒地排查问题、快速止损。在稳定性保障这条道路上,谁来主导,至关重要。我曾身处美团金融团队,深知在应对大流量冲击、快速止损方面的运维主导模式的威力。那种对系统运行状态的精准把握,对预案执行的果断高效......
  • 别再“硬扛”了!稳定性保障主导权切换硬核指南:运维 or QA,何时“换帅”才能止损?
    相信不少朋友都有过这样的经历:线上告警突如其来,团队成员立刻紧张起来,争分夺秒地排查问题、快速止损。在稳定性保障这条道路上,谁来主导,至关重要。我曾身处美团金融团队,深知在应对大流量冲击、快速止损方面的运维主导模式的威力。那种对系统运行状态的精准把握,对预案执行的果断高效......
  • 别再“硬扛”了!稳定性保障主导权切换硬核指南:运维 or QA,何时“换帅”才能止损?
    相信不少朋友都有过这样的经历:线上告警突如其来,团队成员立刻紧张起来,争分夺秒地排查问题、快速止损。在稳定性保障这条道路上,谁来主导,至关重要。我曾身处美团金融团队,深知在应对大流量冲击、快速止损方面的运维主导模式的威力。那种对系统运行状态的精准把握,对预案执行的果断高效......