首页 > 其他分享 >一、Spring Boot集成Spring Security之自动装配

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

时间:2024-10-11 15:44:37浏览次数:10  
标签:return Spring Boot SecurityProperties user Security class

一、Spring Boot集成Spring Security专栏

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

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

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

三、创建Spring Boot项目

  1. 创建Spring Boot项目,目录结构如下

    8c8ee28f2cdf81127643a3901b4833f

  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>

四、查看自动装配配置类

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

    1728632355558

五、自动装配配置类之SecurityAutoConfiguration

1、部分源码

@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

1)、部分源码

@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 {

	}

}

2)、主要作用

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

image-20241010174140639

4、@EnableWebSecurity

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;

}

2)、主要作用

  1. 导入WebSecurityConfiguration
  2. 导入HttpSecurityConfiguration

5、WebSecurityConfiguration

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();
	}
}

2)、主要作用

  1. 两种方式注册过滤器链:
    • 继承WebSecurityConfigurerAdapter(本质是实现SecurityConfigurer接口) (已弃用)
    • 直接向Spring容器中注册SecurityFilterChain对象
  2. 没有默认的过滤器链时,使用WebSecurityConfigurerAdapter中默认配置生成过滤器链
  3. 根据配置的SecurityFilterChain集合构建FilterChainProxy类型的对象并注入到Spring容器中名称为springSecurityFilterChain

6、HttpSecurityConfiguration

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;
	}
}

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中的User类
public static class User {
		private String name = "user";
		private String password = UUID.randomUUID().toString();
		private List<String> roles = new ArrayList<>();
	}
  1. 通过配置文件可以修改默认用户名、密码、角色(示例如下)

image-20241010174253004

七、自动装配配置类之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

标签:return,Spring,Boot,SecurityProperties,user,Security,class
From: https://www.cnblogs.com/sanxiaolq/p/18458562

相关文章

  • 如何在springboot中,全局配置produces="text/plain;charset=UTF-8"
    为什么要使用produces="text/plain;charset=UTF-8"?当不用这个配置时,接口返回的数据,是有斜杠的 配置后,就正常了 以前我的配置方式,是在每个接口上,都添加上produces="text/plain;charset=UTF-8"。但是这样显示不太好,每个接口都加的话,会比较耗费时间如何做到全局配置使用W......
  • 基于java+springboot的社区心理健康服务平台系统小程序
    基于java+springboot的社区心理健康服务平台系统,旨在为社区居民提供全面的心理健康支持。后端运用springboot构建稳定可靠的服务,负责处理用户信息管理、心理咨询师资源整合、心理测评工具管理以及预约咨询安排等核心业务,与数据库有效交互以存储用户心理健康档案、咨询......
  • 基于java+springboot的社区汽车共享平台系统
    基于java+springboot的社区汽车共享平台系统,致力于为社区居民提供便捷的汽车共享服务。后端采用springboot构建,高效处理车辆信息管理、用户认证与授权、预订流程控制及费用结算等业务,与数据库紧密交互确保车辆状态、用户信息及预订记录准确存储与快速检索。前端利用相......
  • 基于SpringBoot+Vue的文学创作交流论坛系统设计与实现(源码+lw+部署+讲解)
    技术环境jdk版本:1.8及以上ide工具:Eclipse或者IDEA数据库:mysql5.7编程语言:Javajava框架:SpringBootmaven:3.6.1详细技术:HTML+CSS+JAVA+SpringBoot+MYSQL+VUE+MAVEN功能设计课题主要采用java技术和MySQL数据库技术以及springboot框架进行开发。系统主要包......
  • 基于SpringBoot+Vue的多媒体素材管理系统设计与实现(源码+lw+部署+讲解)
    技术环境jdk版本:1.8及以上ide工具:Eclipse或者IDEA数据库:mysql5.7编程语言:Javajava框架:SpringBootmaven:3.6.1详细技术:HTML+CSS+JAVA+SpringBoot+MYSQL+VUE+MAVEN功能设计该系统采用了java技术、SpringBoot框架,连接MySQL数据库,具有较高的信息传输速率与......
  • springboot企业招聘管理系统
    基于springboot+vue实现的企业招聘管理系统 (源码+L文+ppt)4-089   4.3系统结构设计  构图是系统的体系结构,体系结构是体系结构体系的重要组成部分。系统的总体结构设计如图4-2所示。   图4-2系统总体架构图4.4数据库设计  4.4.1数据库设计原则  ......
  • springboot酒店在线预订系统
    基于springboot+vue实现的酒店在线预订系统 (源码+L文+ppt)4-082                                   4.2 系统结构设计  构图是系统的体系结构,体系结构是体系结构体系的一部分,体系结构体系是体系结......
  • 【JAVA开源】基于Vue和SpringBoot卫生健康系统
    本文项目编号T076,文末自助获取源码\color{red}{T076,文末自助获取源码}......
  • com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:jar:unknown was n
    com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:jar:unknownwasnotfoundinhttp://maven.aliyun.com/nexus/content/repositories/central/duringapreviousattempt.Thisfailurewascachedinthelocalrepositoryandresolutionisnotreatte......
  • 基于Spring Boot的师生共评作业管理平台:提高教学效率
    摘要随着信息互联网信息的飞速发展,无纸化作业变成了一种趋势,针对这个问题开发一个专门适应师生作业交流形式的网站。本文介绍了师生共评的作业管理系统的开发全过程。通过分析企业对于师生共评的作业管理系统的需求,创建了一个计算机管理师生共评的作业管理系统的方案。文章......