SpringSecurity 核心组件

news2024/11/23 9:00:03

文章目录

  • SpringSecurity 结构
  • 组件:SecurityContextHolder
  • 组件:Authentication
  • 组件:UserDetailsService
  • 组件:GrantedAuthority
  • 组件总结

SpringSecurity 结构

在SpringSecurity中的jar分为4个,作用分别为

jar作用
spring-security-coreSpringSecurity的核心jar包,认证和授权的核心代码都在这里面
spring-security-config如果使用Spring Security XML名称空间进行配置或Spring Security的
Java configuration支持,则需要它
spring-security-web用于Spring Security web身份验证服务和基于url的访问控制
spring-security-test测试单元

组件:SecurityContextHolder

在spring-security-core中的SecurityContextHolder,是一个非常基础的对象,存储了当前应用的上下文SecurityContext,而在SecurityContext可以获取Authentication对象。也就是当前认证的相关信息会存储在Authentication对象中。

image.png

默认情况下,SecurityContextHolder是通过 ThreadLocal来存储对应的信息的。也就是在一个线程中我们可以通过这种方式来获取当前登录的用户的相关信息。而在SecurityContext中就只提供了对Authentication对象操作的方法

public interface SecurityContext extends Serializable {

	Authentication getAuthentication();

	void setAuthentication(Authentication authentication);

}

xxxStrategy的各种实现

image.png

策略实现说明
GlobalSecurityContextHolderStrategy把SecurityContext存储为static变量
InheritableThreadLocalSecurityContextStrategy把SecurityContext存储在InheritableThreadLocal中
InheritableThreadLocal解决父线程生成的变量传递到子线程中进行使用
ThreadLocalSecurityContextStrategy把SecurityContext存储在ThreadLocal中

组件:Authentication

Authentication是一个认证对象。在Authentication接口中声明了如下的相关方法。

public interface Authentication extends Principal, Serializable {

	// 获取认证用户拥有的对应的权限
	Collection<? extends GrantedAuthority> getAuthorities();

	// 获取哦凭证
	Object getCredentials();

    // 存储有关身份验证请求的其他详细信息。这些可能是 IP地址、证书编号等
	Object getDetails();

     // 获取用户信息 通常是 UserDetails 对象
	Object getPrincipal();

    // 是否认证
	boolean isAuthenticated();

    // 设置认证状态
	void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;

}

image.png

基于上面讲解的三者的关系,在项目中如下来获取当前登录的用户信息了。

    public String hello(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if(principal instanceof UserDetails){
            UserDetails userDetails = (UserDetails) principal;
            System.out.println(userDetails.getUsername());
            return "当前登录的账号是:" + userDetails.getUsername();
        }
        return "当前登录的账号-->" + principal.toString();
    }

调用 getContext()返回的对象是 SecurityContext接口的一个实例,这个对象就是保存在线程中的。接下来将看到,Spring Security中的认证大都返回一个 UserDetails的实例作为principa。

组件:UserDetailsService

在上面的关系中可以看到在Authentication中存储当前登录用户的是Principal对象,而通常情况下Principal对象可以转换为UserDetails对象。UserDetails是Spring Security中的一个核心接口。它表示一个principal,但是是可扩展的、特定于应用的。可以认为 UserDetails是数据库中用户表记录和Spring Security在 SecurityContextHolder中所必须信息的适配器。

public interface UserDetails extends Serializable {

	// 对应的权限
	Collection<? extends GrantedAuthority> getAuthorities();

	// 密码
	String getPassword();

	// 账号
	String getUsername();

	// 账号是否过期
	boolean isAccountNonExpired();

	// 是否锁定
	boolean isAccountNonLocked();

	// 凭证是否过期
	boolean isCredentialsNonExpired();

	// 账号是否可用
	boolean isEnabled();

}

而这个接口的默认实现就是 User

image.png

那么这个UserDetails对象什么时候提供呢?在上文介绍的数据库认证的Service中我们就用到了,有一个特殊接口 UserDetailsService,在这个接口中定义了一个loadUserByUsername的方法,接收一个用户名,来实现根据账号的查询操作,返回的是一个 UserDetails对象。

public interface UserDetailsService {

	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

}

UserDetailsService接口的实现有如下:

image.png

Spring Security提供了许多 UserDetailsSerivice接口的实现,包括使用内存中map的实现(InMemoryDaoImpl 低版本 InMemoryUserDetailsManager)和使用JDBC的实现(JdbcDaoImpl)。但在实际开发中我们更喜欢自己来编写,比如UserServiceImpl我们的案例


/**
 * UserService接口的实现类
 */
@Service
public class UserServiceImpl extends UserDetailsService {

    @Autowired
    UserMapper userMapper;

    /**
     * 根据账号密码验证的方法
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser user = userMapper.queryByUserName(username);
        System.out.println("---------->"+user);
        if(user != null){
            // 账号对应的权限
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            // 说明账号存在 {noop} 非加密的使用
            UserDetails details = new User(user.getUserName()
                    ,user.getPassword()
                    ,true
                    ,true
                    ,true
                    ,true
                    ,authorities);
            return details;
        }
        throw new UsernameNotFoundException("账号不存在...");

    }
}

组件:GrantedAuthority

在Authentication中看到不光关联了Principal还提供了一个getAuthorities()方法来获取对应的GrantedAuthority对象数组。

public interface GrantedAuthority extends Serializable {


	String getAuthority();

}

组件总结

核心对象作用
SecurityContextHolder用于获取SecurityContext
SecurityContext存放了Authentication和特定于请求的安全信息
Authentication特定于Spring Security的principal
GrantedAuthority对某个principal的应用范围内的授权许可
UserDetail提供从应用程序的DAO或其他安全数据源构建Authentication对象所需的信息
UserDetailsService接受String类型的用户名,创建并返回UserDetail

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1021039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

idea配置tomcat项目,运行起来却无法访问项目

好长时间都没碰使用tomcat部署的老项目了 最近碰到一个tomcat老项目&#xff0c;都忘记怎么用idea配置了 按记忆配置好之后&#xff0c;启动tomcat&#xff0c;却怎么也访问不了项目 最后才发现根本没有启动编译后的项目代码 只需要右键项目&#xff0c;选择Open Module Se…

如何通过百度SEO优化提升网站排名(掌握基础概念,实现有效优化)

随着互联网的发展&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;成为了网站优化中不可或缺的一部分。在中国&#xff0c;百度搜索引擎占据着主导地位&#xff0c;因此掌握百度SEO概念和优化技巧对网站的排名和曝光非常重要。 百度SEO排名的6个有效方法&#xff1a; 首…

福建企业可以申请泛域名https证书吗

https域名https证书中有一种比较特殊的https证书&#xff0c;可以用一张https证书保护主域名以及主域名下所有子域名&#xff0c;这种证书通常被称为通配符https证书或泛域名https证书。那么企业可以申请泛域名https证书吗?今天就随SSL盾小编了解泛域名https证书。 1.泛域名h…

共享门店模式:让你的连锁门店变成金鸡母

共享门店模式是一种创新的经营方式&#xff0c;它可以让门店的资源和收益与其他人共享&#xff0c;实现互利共赢。共享门店模式有两种主要形式&#xff1a;投资型和消费型。投资型共享门店模式需要股东投入一定的资金&#xff0c;用于锁客和获取分红收益。消费型共享门店模式则…

【免费内网穿透】cpolar从0开始使用

cpolar从0开始使用 具体步骤cpolar下载注册安装 安装启动创建或修改启动 公网远程访问内网web站点初步完成 最近学习到的新东西。 原理类似于使用cpolar的服务器进行跳转 具体步骤 下载CPOLAR 在您的机器上下载并运行cpolar客户端&#xff0c;并为其提供一个本地的网络服务的…

如何合并pdf?三种合并方法教会你

如何合并pdf&#xff1f;合并PDF文件可以将多个PDF文档合并为一个文件&#xff0c;提高文件管理的效率和便利性。无论是为了整理和归档文件&#xff0c;还是为了方便共享和传输文件&#xff0c;合并PDF都是非常实用的操作。通过合并PDF&#xff0c;可以将相关的文件整合在一起&…

项目管理:管理成果是控制还是天意?项目经理的责任是什么?

有人坚信管理具有决定性的作用&#xff0c;主张管理者需对组织的成功或失败负全责。 另一些人则认为&#xff0c;管理者对管理成果的影响其实相当有限&#xff0c;因为存在许多他们无法控制的因素。 组织的成功或失败往往更多地归因于这些无法控制的因素&#xff0c;而非管理者…

浏览器代理解决方案

当谈到网络浏览器&#xff0c; 浏览器 无疑是最受欢迎和广泛使用的选项之一。然而&#xff0c;你可能已经注意到&#xff0c; 浏览器并不原生支持 SOCKS5 代理协议。不过&#xff0c;别担心&#xff01;在本文中&#xff0c;我将与你分享一些解决方案&#xff0c;让你能够在 浏…

黑马JVM总结(十三)

&#xff08;1&#xff09;软引用_引用队列 上面我们们使用软引用我们发现在内存不足时&#xff0c;会把软引用对应的Byte数组对象&#xff0c;进行一个释放&#xff0c;但是我们发现遍历lIst集合的时候一些软引用的对象已经是null了&#xff0c;这些没必要在把它们保存到List…

哨兵模式(sentinel)

为什么需要哨兵模式 redis的主从复制模式能够缓解“读压力”&#xff0c;但是存在两个明显问题。 主节点发生故障&#xff0c;进行主节点切换的过程比较复杂&#xff0c;需要人工参与&#xff0c;导致故障恢复时间无法保障主节点通过主从复制模式将读压力分散出去&#xff0c…

【算法】算法设计与分析 课程笔记 第一章 概述

第一章 算法概述 算法的性质 算法的四个性质&#xff1a;输入、输出、确定性和有穷性。 算法的时间复杂度 1. 常见的时间复杂度 常数阶 O(1) 对数阶 O(log n) 线性阶 O(n) 线性对数阶 O(nlog n) 平方阶 O(n^2) 立方阶 O(n^3) k 次方阶 O(n^k) 指数阶 O(2^n) 注&…

Prompt 策略:代码库 AI 助手的语义化搜索设计

在过去的一周里&#xff0c;为了更好的构建 AI Agent 框架 Chocolate Factory&#xff08;以下简称 CF&#xff09;&#xff0c;我们加入了一个新的应用&#xff1a;代码库 AI 助手。 在设计时&#xff0c;为了更好的在框架底层提供这种能力&#xff0c;我们参阅了 Bloop 应用、…

科研小工具|慢性阻塞性肺疾病全球创议

简介 慢性阻塞性肺疾病全球创议&#xff08;the Global Initiative for Chornic Obstructive Lung Disease&#xff0c;GOLD&#xff09;是慢性阻塞性肺疾病&#xff08;COPD&#xff09;诊断、治疗与预防在全球范围内的标准。颁布GOLD的目的在于&#xff0c;增加医疗卫生工作…

pdd24版滑块

最近pdd改版了&#xff0c;在原来的基础之上加了一个content字段&#xff0c;然后pdd滑块分为两个大类。 一个是22类型的&#xff0c;在之前的文章里面有介绍&#xff0c;感兴趣也可以去看看。 详情的滑块跟普通的版本不同&#xff0c;但是有的算法也沿用了之前22版的东西&a…

【Seata】05 - Seata Saga 模式简单整理、Docker 部署 Nacos 单机(基于 Jpom)相关配置

文章目录 前言参考目录Saga 模式知识点简单整理1、适用场景、优缺点2、Saga 模式的使用3、可能出现的问题以及解决方法 Docker 部署 Nacos 单机&#xff08;基于 Jpom&#xff09;步骤 1&#xff1a;拉取镜像步骤 2&#xff1a;构建容器步骤 3&#xff1a;Nacos 设置 Seata 配置…

安装Python第三方库

视频版教程 Python3零基础7天入门实战视频教程 在Python的标准安装中&#xff0c;包含了一组自带的模块&#xff0c;这些模块被成为“标准库”。比如常用的math,random,datetime,os,json等等。 此外&#xff0c;还有很多的第三方模块&#xff0c;或者叫做库也行&#xff0c;叫…

TienChin 渠道管理-配置校验失败信息

新建 ValidationMessages.properties&#xff1a; channel.name.notnull渠道名称不能为空 channel.type.notnull渠道类型不能为空 channel.status.notnull渠道状态不能为空 channel.type.invalid渠道类型无效 channel.status.invalid渠道状态无效

linux上安装redis

这篇文章简单地介绍一下怎么在linux虚拟机上完成redis的安装。 首先&#xff0c;访问Redis官网&#xff0c;点击首页的【Get Started】&#xff0c;然后点击Install Redis on Linux 然后按照页面内容提示&#xff0c;在Ubuntu上安装redis 只需要在终端依次输入以下命令&#xf…

面试官:Vue实例挂载的过程中发生了什么?

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 一、思考 一、分析 三、结论 一、思考 我们都听过知其然知其所以然这句话 那么不知道大家是否思考过new Vue()这…

权限提升WIN篇(腾讯云,CS,MSF)

溢出漏洞 信息收集 操作系统版本ver&#xff0c;systeminfo漏洞补丁信息systeminfo操作系统位数systeminfo杀软防护tasklist /svc网络netstat -ano,ipconfig当前权限whoami 筛选EXP 根据前面的信息收集中的系统版本&#xff0c;位数和补丁情况筛选出合适的EXP 提权 根据EX…