一、Spring Boot集成Spring Security之自动装配

Spring Boot集成Spring Security之自动装配介绍

  • 一、实现功能及软件版本说明
  • 二、创建Spring Boot项目
  • 三、查看自动装配配置类
  • 四、自动装配配置类之SecurityAutoConfiguration
    • 1、SecurityAutoConfiguration部分源码
    • 2、主要作用
    • 3、SpringBootWebSecurityConfiguration
      • 3.1、SpringBootWebSecurityConfiguration部分源码
      • 3.2、主要作用
    • 4、@EnableWebSecurity
      • 4.1、部分源码
      • 4.2、主要作用
    • 5、WebSecurityConfiguration
      • 5.1、部分源码
      • 5.2、主要作用
    • 6、HttpSecurityConfiguration
      • 6.1、部分源码
      • 6.2、主要作用
  • 五、自动装配配置类之UserDetailsServiceAutoConfiguration
    • 1、部分源码
    • 2、主要作用
  • 六、自动装配配置类之SecurityFilterAutoConfiguration
    • 1、部分源码
    • 2、主要作用

一、实现功能及软件版本说明

  1. 使用Spring Boot集成Spring Security实现Servlet项目的安全个性化配置
  2. Spring Boot版本:2.7.18
  3. Spring Security版本:5.7.11

二、创建Spring Boot项目

  1. 创建Spring Boot项目,目录结构如下
    Spring Boot目录结构
  2. 引入Spring Security包,完成pom.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
        <relativePath/>
    </parent>

    <groupId>com.yu</groupId>
    <artifactId>spring-boot-security2-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-security2-demo</name>
    <description>Spring Boot集成Spring Security样例</description>

    <properties>
        <java.version>8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

</project>

三、查看自动装配配置类

  1. 查看Security Servlet相关自动装配配置类
    自动装配配置

四、自动装配配置类之SecurityAutoConfiguration

1、SecurityAutoConfiguration部分源码

@AutoConfiguration
@ConditionalOnClass(DefaultAuthenticationEventPublisher.class)
@EnableConfigurationProperties(SecurityProperties.class)
@Import({ SpringBootWebSecurityConfiguration.class, SecurityDataConfiguration.class })
public class SecurityAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(AuthenticationEventPublisher.class)
	public DefaultAuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher publisher) {
		return new DefaultAuthenticationEventPublisher(publisher);
	}

}

2、主要作用

  1. 导入SpringBootWebSecurityConfiguration

3、SpringBootWebSecurityConfiguration

3.1、SpringBootWebSecurityConfiguration部分源码

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnDefaultWebSecurity
	static class SecurityFilterChainConfiguration {

		@Bean
		@Order(SecurityProperties.BASIC_AUTH_ORDER)
		SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
			http.authorizeRequests().anyRequest().authenticated();
			http.formLogin();
			http.httpBasic();
			return http.build();
		}

	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
	@ConditionalOnClass(EnableWebSecurity.class)
	@EnableWebSecurity
	static class WebSecurityEnablerConfiguration {

	}

}

3.2、主要作用

  1. 默认Security配置(Spring容器中没有SecurityFilterChain和WebSecurityConfigurerAdapter)时,向Spring容器中注入默认过滤器链,即用户没有自定义过滤器链时,生成默认过滤器链
    默认过滤器链
  2. Spring容器中不存在名称为springSecurityFilterChain对象时,启用WebSecurity,即用户未显示的启用WebSecurity时,隐式的启用WebSecurity
    在这里插入图片描述

4、@EnableWebSecurity

4.1、部分源码

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import({ WebSecurityConfiguration.class, SpringWebMvcImportSelector.class, OAuth2ImportSelector.class,
		HttpSecurityConfiguration.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {

	/**
	 * Controls debugging support for Spring Security. Default is false.
	 * @return if true, enables debug support with Spring Security
	 */
	boolean debug() default false;

}

4.2、主要作用

  1. 导入WebSecurityConfiguration
  2. 导入HttpSecurityConfiguration

5、WebSecurityConfiguration

5.1、部分源码

@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
	public Filter springSecurityFilterChain() throws Exception {
		boolean hasConfigurers = this.webSecurityConfigurers != null && !this.webSecurityConfigurers.isEmpty();
		boolean hasFilterChain = !this.securityFilterChains.isEmpty();
		Assert.state(!(hasConfigurers && hasFilterChain),
				"Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.");
		if (!hasConfigurers && !hasFilterChain) {
			WebSecurityConfigurerAdapter adapter = this.objectObjectPostProcessor
					.postProcess(new WebSecurityConfigurerAdapter() {
					});
			this.webSecurity.apply(adapter);
		}
		for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {
			this.webSecurity.addSecurityFilterChainBuilder(() -> securityFilterChain);
			for (Filter filter : securityFilterChain.getFilters()) {
				if (filter instanceof FilterSecurityInterceptor) {
					this.webSecurity.securityInterceptor((FilterSecurityInterceptor) filter);
					break;
				}
			}
		}
		for (WebSecurityCustomizer customizer : this.webSecurityCustomizers) {
			customizer.customize(this.webSecurity);
		}
		return this.webSecurity.build();
	}
}

5.2、主要作用

  1. 根据配置的SecurityFilterChain集合构建springSecurityFilterChain对象并注入到Spring容器中

6、HttpSecurityConfiguration

6.1、部分源码

@Configuration(proxyBeanMethods = false)
class HttpSecurityConfiguration {

	@Bean(HTTPSECURITY_BEAN_NAME)
	@Scope("prototype")
	HttpSecurity httpSecurity() throws Exception {
		WebSecurityConfigurerAdapter.LazyPasswordEncoder passwordEncoder = new WebSecurityConfigurerAdapter.LazyPasswordEncoder(
				this.context);
		AuthenticationManagerBuilder authenticationBuilder = new WebSecurityConfigurerAdapter.DefaultPasswordEncoderAuthenticationManagerBuilder(
				this.objectPostProcessor, passwordEncoder);
		authenticationBuilder.parentAuthenticationManager(authenticationManager());
		authenticationBuilder.authenticationEventPublisher(getAuthenticationEventPublisher());
		HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());
		// @formatter:off
		http
			.csrf(withDefaults())
			.addFilter(new WebAsyncManagerIntegrationFilter())
			.exceptionHandling(withDefaults())
			.headers(withDefaults())
			.sessionManagement(withDefaults())
			.securityContext(withDefaults())
			.requestCache(withDefaults())
			.anonymous(withDefaults())
			.servletApi(withDefaults())
			.apply(new DefaultLoginPageConfigurer<>());
		http.logout(withDefaults());
		// @formatter:on
		applyDefaultConfigurers(http);
		return http;
	}
}

6.2、主要作用

  1. Spring容器中注册HttpSecurity对象
  2. httpSecurity用于配置构建自定义过滤器链

五、自动装配配置类之UserDetailsServiceAutoConfiguration

1、部分源码

@AutoConfiguration
@ConditionalOnClass(AuthenticationManager.class)
@ConditionalOnBean(ObjectPostProcessor.class)
@ConditionalOnMissingBean(
		value = { AuthenticationManager.class, AuthenticationProvider.class, UserDetailsService.class,
				AuthenticationManagerResolver.class },
		type = { "org.springframework.security.oauth2.jwt.JwtDecoder",
				"org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector",
				"org.springframework.security.oauth2.client.registration.ClientRegistrationRepository",
				"org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository" })
public class UserDetailsServiceAutoConfiguration {
	@Bean
	@Lazy
	public InMemoryUserDetailsManager inMemoryUserDetailsManager(SecurityProperties properties,
			ObjectProvider<PasswordEncoder> passwordEncoder) {
		SecurityProperties.User user = properties.getUser();
		List<String> roles = user.getRoles();
		return new InMemoryUserDetailsManager(User.withUsername(user.getName())
			.password(getOrDeducePassword(user, passwordEncoder.getIfAvailable()))
			.roles(StringUtils.toStringArray(roles))
			.build());
	}
	private String getOrDeducePassword(SecurityProperties.User user, PasswordEncoder encoder) {
		String password = user.getPassword();
		if (user.isPasswordGenerated()) {
			logger.warn(String.format(
					"%n%nUsing generated security password: %s%n%nThis generated password is for development use only. "
							+ "Your security configuration must be updated before running your application in "
							+ "production.%n",
					user.getPassword()));
		}
		if (encoder != null || PASSWORD_ALGORITHM_PATTERN.matcher(password).matches()) {
			return password;
		}
		return NOOP_PASSWORD_PREFIX + password;
	}

2、主要作用

  1. 用户未自定义认证接口时,生成默认认证接口inMemoryUserDetailsManager(基于内存用户认证)
  2. 生成默认名称为user,密码为随机生成的uuid(项目启动时会打印在控制台中),角色为空的用户存入内存中
#UserDetailsServiceAutoConfiguration.inMemoryUserDetailsManager方法中获取user对象
SecurityProperties.User user = properties.getUser();
#SecurityProperties中的Userpublic static class User {
		private String name = "user";
		private String password = UUID.randomUUID().toString();
		private List<String> roles = new ArrayList<>();
	}
  1. 通过配置文件可以修改默认用户名、密码、角色(示例如下)
    配置默认用户名、密码、角色

六、自动装配配置类之SecurityFilterAutoConfiguration

1、部分源码

@AutoConfiguration(after = SecurityAutoConfiguration.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(SecurityProperties.class)
@ConditionalOnClass({ AbstractSecurityWebApplicationInitializer.class, SessionCreationPolicy.class })
public class SecurityFilterAutoConfiguration {

	private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;

	@Bean
	@ConditionalOnBean(name = DEFAULT_FILTER_NAME)
	public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(
			SecurityProperties securityProperties) {
		DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean(
				DEFAULT_FILTER_NAME);
		registration.setOrder(securityProperties.getFilter().getOrder());
		registration.setDispatcherTypes(getDispatcherTypes(securityProperties));
		return registration;
	}

	private EnumSet<DispatcherType> getDispatcherTypes(SecurityProperties securityProperties) {
		if (securityProperties.getFilter().getDispatcherTypes() == null) {
			return null;
		}
		return securityProperties.getFilter()
			.getDispatcherTypes()
			.stream()
			.map((type) -> DispatcherType.valueOf(type.name()))
			.collect(Collectors.toCollection(() -> EnumSet.noneOf(DispatcherType.class)));
	}

}

2、主要作用

  1. 注册DelegatingFilterProxyRegistrationBean(委托过滤器代理注册Bean)
  2. 设置代理目标Bean对象名称为springSecurityFilterChain

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Prometheus监控k8s环境构建

传统架构中比较流行的监控工具有 Zabbix、Nagios 等&#xff0c;这些监控工具对于 Kubernetes 这类云平台的监控不是很友好&#xff0c;特别是当 Kubernetes 集群中有了成千上万的容器后更是如此&#xff0c;本章节学习下一代的云原生监控平台---Prometheus。 一、基于kuberne…

【从零开始实现stm32无刷电机FOC】【实践】【7.2/7 完整代码编写】

目录 stm32cubemx配置芯片选择工程配置stm32基础配置SPI的配置定时器的配置ADC的配置中断优先级的配置生成工程 工程代码编写FOC代码结构搭建电机编码器角度读取PWM产生FOC开环代码编写确定电机正负旋转方向电机旋转速度计算多圈逻辑角度电流采样极对数转子角度确定 闭环控制控…

The Open Group 2024生态系统架构·可持续发展年度大会全面解读

在全球数字化转型加速的时代背景下&#xff0c;人工智能技术正以前所未有的速度重塑各行各业的生态系统。尤其是随着ChatGPT、Sora等技术的爆发&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;技术在多个领域展现出超越人类的能力&#xff0c;AGI&#xff08;通用人…

Stable Diffusion绘画 | SDXL模型使用注意事项

注意事项 SDXL模型的使用&#xff0c;对电脑配置要求更高&#xff0c;需要 8GB 以上显存的显卡SDXL模型兼容性不太好&#xff0c;容易出现错误&#xff0c;对 Mac 电脑不友好只能选择 SDXL模型 训练的 LoRA 使用不能使用旧的 VAE文件 SDXL 专用 VAE 文件&#xff1a;sdxl_vae.…

HTML流光爱心

文章目录 序号目录1HTML满屏跳动的爱心&#xff08;可写字&#xff09;2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4HTML情人节快乐5HTML蓝色爱心射线6HTML跳动的爱心&#xff08;简易版&#xff09;7HTML粒子爱心8HTML蓝色动态爱心9HTML跳动的爱心&#xff08;双心版&#xff09;1…

类和对象(3)

博客ID&#xff1a;LanFuRenC系列专栏&#xff1a;C语言重点部分 C语言注意点 C基础 Linux 数据结构 C注意点 声明等级&#xff1a;黑色->蓝色->红色 欢迎新粉加入&#xff0c;会一直努力提供更优质的编程博客&#xff0c;希望大家三连支持一下啦 目录 1.拷贝构造 …

ACM第三次考核题解

ACM第三次考核题解 题目序号难度题目编号题目考察知识点1签到题A这是一道很难的题&#xff01;&#xff01;&#xff01;输出2迷之难度F神说要有光&#xff0c;于是有了手电筒贪心3简单BThis is a real English problem&#xff01;思维 英语4简单C玩具简单排序5简单I“近义词…

速通数据结构与算法第六站 树堆

系列文章目录 速通数据结构与算法系列 1 速通数据结构与算法第一站 复杂度 http://t.csdnimg.cn/sxEGF 2 速通数据结构与算法第二站 顺序表 http://t.csdnimg.cn/WVyDb 3 速通数据结构与算法第三站 单链表 http://t.csdnimg.cn/cDpcC 4 速通…

一文上手SpringSecurity【九】

在校验token的过滤器当中, 由于需要根据用户名称, 去查询出要认证的对象,然后再去数据库当中查询出角色列表、权限列表.频繁的操作数据库,可能会带来性能瓶颈, 那么我们该如何解决呢? 我们可以引入Redis, 将认证的对象,存储到Redis当中,在校验token的过滤器当中,可以直接从Red…

9.29 LeetCode 3304、3300、3301

思路&#xff1a; ⭐进行无限次操作&#xff0c;但是 k 的取值小于 500 &#xff0c;所以当 word 的长度大于 500 时就可以停止操作进行取值了 如果字符为 ‘z’ &#xff0c;单独处理使其变为 ‘a’ 得到得到操作后的新字符串&#xff0c;和原字符串拼接 class Solution { …

ServletContainerInitializer接口详解

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhlServletContainerInitializer概述 ServletContainerInitializer是Servlet 3.0规范中引入的一个接口,它的主要目的是允许开发者在Servlet容器(如Tomcat、Jetty等)启动时执行一些自定义的初始化代…

synchronized相关知识

1、对象头Markword 2、锁升级过程 无锁 偏向锁&#xff1a;只有一个线程过来加锁&#xff0c;Markword对应变化&#xff1a;偏向线程ID存储当前线程ID&#xff0c;偏向锁标志位置成1&#xff0c;锁标志位置为01&#xff1b;此后如果当前线程再次获取锁&#xff0c;只需对比偏…

《十年国庆游,洞察中国旅游新趋势》

作者&#xff1a;侯炯 一、十年国庆旅游数据总览 过去十年&#xff0c;中国国庆旅游市场呈现出丰富的变化和强劲的发展态势。从接待游客人次来看&#xff0c;2014 年接待国内游客 4.75 亿人次&#xff0c;到 2019 年已增长至 7.82 亿人次&#xff0c;2023 年国内旅游出游人数更…

【预备理论知识——1】深度学习:概率论概述

简单地说&#xff0c;机器学习就是做出预测。 概率论 掷骰子 假设我们掷骰子&#xff0c;想知道看到1的几率有多大&#xff0c;而不是看到另一个数字。 如果骰子是公平的&#xff0c;那么所有六个结果{1,…, 6}都有相同的可能发生&#xff0c; 因此我们可以说 1 发生的概率为1…

【数据结构】图的最小生成树

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C游记》《进击的C》《Linux迷航》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、最小生成树的概念二、Kruskal算法2.1 思想2.2 实现 三、Prim算法3.1 思想3.2 实现 四、Kruskal和Prim的对比…

container_of 函数的分析

这个函数的目的是&#xff0c; 通过结构体里面的内容 找到 大结构体的 基地址。 函数的原型是&#xff1a;  &#xff30;&#xff34;&#xff32;是指针 &#xff54;&#xff59;&#xff50;&#xff45; &#xff0c; &#xff4d;&#xff45;&#xff4d;&#xff…

新手上路:Anaconda虚拟环境创建和配置以使用PyTorch和DGL

文章目录 前言步骤 1: 安装 Anaconda步骤 2: 创建新的 Anaconda 环境步骤 3: 安装最新版本的 PyTorch步骤 4: 安装特定版本的 PyTorch步骤 5: 安装最新版本的 DGL步骤 6: 安装特定版本的 DGL步骤 7: Pycharm中使用虚拟环境解释器第一种情况&#xff1a;创建新项目第二种情况&am…

Word办公自动化的一些方法

1.Word部分内容介绍 word本身是带有格式的一种文档&#xff0c;有人说它本质是XML&#xff0c;所以一定要充分利用标记了【样式】的特性来迅速调整【格式】&#xff0c;从而专心编辑文档内容本身。 样式&#xff08;集&#xff09; 编号&#xff08;多级关联样式编号&#xff…

Tomcat系列漏洞复现

CVE-2017-12615——Tomcat put⽅法任意⽂件写⼊漏洞 漏洞描述 当 Tomcat运⾏在Windows操作系统时&#xff0c;且启⽤了HTTP PUT请求⽅法&#xff08;例如&#xff0c;将 readonly初始化参数由默认值设置为false&#xff09;&#xff0c;攻击者将有可能可通过精⼼构造的攻击请求…

探索 Snowflake 与 Databend 的云原生数仓技术与应用实践 | Data Infra NO.21 回顾

上周六&#xff0c;第二十一期「Data Infra 研究社」在线上与大家相见。活动邀请到了西门子数据分析师陈砚林与 Databend 联合创始人王吟&#xff0c;为我们带来了一场关于 Snowflake 和 Databend 的技术探索。Snowflake&#xff0c;这个市值曾超过 700 亿美元的云原生数据仓库…