SpringSecurity------引入方式和配置(一)
1、使用Spring Boot构建
优先考虑使用Spring Initializr或是IDE软件集成的Spring Initializr引入Starter,或者也可以手动添加maven依赖引入:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>5.5.0-SNAPSHOT</version>
</dependency>
</dependencies>
2、不使用Spring Boot构建
当不使用Spring Boot构建Spring Security应用程序,优先考虑使用Spring Security’s BOM,可以保证Spring Security版本号在整个项目中的一致性:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>{spring-security-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
最小限度使用Spring Security的典型Maven依赖如下:
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
</dependencies>
很多用户在使用Spring Security时,由于依赖传递的冲突导致奇怪的类路径加载问题,最简单的解决办法是在pom文件中使用spring-framework-bom管理:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>5.3.2-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3、Maven 仓库
所有GA版本(以 .RELEASE结尾的版本) 都部署在Maven Central,所以不需要在POM文件中声明附加的Maven仓库。
如果使用SNAPSHOT版本,需要保证在POM文件中定义了Spring Snapshot仓库地址,如下所示:
<repositories>
<repository>
<id>spring-snapshot</id>
<name>Spring Snapshot Repository</name>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
如果使用Milestone或是Candidate版本,需要保证在POM文件中定义了Spring Milestone仓库地址,如下所示:
<repositories>
<repository>
<id>spring-milestone</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
4、Spring MVC使用Spring Security的Java Configuration配置步骤
4.1 、配置UserDetailsService
使用java配置单一的初始化用户名和密码,以下配置会创建一个Servlet Filter,这个Filter会被注入到SecurityFilterChain,SecurityFilterChain就是处理所有安全认证和鉴权的类,这个简单的配置会为应用程序添加以下安全机制:
- 所有URL访问都需要鉴权
- 创建一个登录表单
- 创建一个用户名为user,密码为password等表单登录账户
- 允许登出
- CSRF攻击防护
- Session维护
- Security Header集成
- HTTPS传输协议
- X-Content-Type-Options
- Cache Control
- X-XSS-Protection
- X-Frame-Options 阻止点击劫持
- 融入以下可用的Servlet API方法
-
HttpServletRequest#getRemoteUser()
-
HttpServletRequest#getUserPrincipal()
-
HttpServletRequest#isUserInRole(java.lang.String)
-
HttpServletRequest#login(java.lang.String, java.lang.String)
-
HttpServletRequest#logout()
-
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.authentication.builders.*;
import org.springframework.security.config.annotation.web.configuration.*;
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build());
return manager;
}
}
也可以在配置文件中指定初始化用户名和密码
spring.security.user.name=user
spring.security.user.password=password
4.2、注册SecurityFilterChain、引入WebSecurityConfig配置文件
AbstractSecurityWebApplicationInitializer用于注册SecurityFilterChain
import org.springframework.security.web.context.*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
//开启 HttpSessionEventPublisher
@Override
protected boolean enableHttpSessionEventPublisher() {
return true;
}
// ... other overrides ...
}
public class MvcWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebSecurityConfig.class };
}
// ... other overrides ...
}
4.3、配置SecurityFilterChain
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
) //所有请求都需要鉴权
.formLogin(withDefaults())//表单登录
.httpBasic(withDefaults());//HTTP Basic登录
return http.build();
}
4.4、配置多个SecurityFilterChain
@EnableWebSecurity
public class MultiHttpSecurityConfig {
//创建一个用户名密码加载器
@Bean
public UserDetailsService userDetailsService() throws Exception {
UserBuilder users = User.withDefaultPasswordEncoder();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(users.username("user").password("password").roles("USER").build());
manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build());
return manager;
}
//注入一个只拦截/api/开头的URL请求的SecurityFilterChain,这个拦截器顺序为1,有限于formLoginFilterChain执行
@Bean
@Order(1)
public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeHttpRequests(authorize -> authorize
.anyRequest().hasRole("ADMIN")
)
.httpBasic(withDefaults());
return http.build();
}
//注入另一个处理非/api/开头的URL请求的SecurityFilterChain,没有@Order指定排序的拦截器默认是最后执行
@Bean
public SecurityFilterChain formLoginFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults());
return http.build();
}
}
4.5、自定义DSLs
public class CustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> {
private boolean flag;
@Override
public void init(HttpSecurity http) throws Exception {
//添加任何其他配置器都需要在这个init方法中
http.csrf().disable();
}
@Override
public void configure(HttpSecurity http) throws Exception {
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
//这里从ApplicationContext容器中寻找拦截器
CustomFilter customFilter = context.getBean(CustomFilter .class);
customFilter .setFlag(flag);
http.addFilterBefore(customFilter , UsernamePasswordAuthenticationFilter.class);
}
public CustomDsl flag(boolean value) {
this.flag = value;
return this;
}
public static CustomDsl customDsl() {
return new MyCustomDsl();
}
}
注意:HttpSecurity.authorizeRequests()的实现方式和上面的代码类似
通过下面的方式使用自定义的DSLs
@EnableWebSecurity
public class Config {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.apply(customDsl())
.flag(true)
.and()
...;
return http.build();
}
}
可以使用classpath/META-INF/spring.factories文件将自定义的CustomDsl设置为默认加载
org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer = sample.CustomDsl
禁用默认的CustomDsl可以如下配置
@EnableWebSecurity
public class Config {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.apply(customDsl()).disable()
...;
return http.build();
}
}
4.6、Post Processing Configured Objects
为了简化大多数用户的配置,Spring Security的Java Configuration配置方式并没有公开它所配置的每个对象的每个属性。虽然有很好的理由不直接公开每个属性,但用户可能仍然需要更高级的配置选项。 为了解决这个问题,Spring Security引入了ObjectPostProcessor的概念,它可以用来修改或替换Java Configuration创建的许多Object实例。 例如,如果你想在FilterSecurityInterceptor上配置filterSecurityPublishAuthorizationSuccess属性,你可以使用下面的方法:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
public <O extends FilterSecurityInterceptor> O postProcess(
O fsi) {
fsi.setPublishAuthorizationSuccess(true);
return fsi;
}
})
);
return http.build();
}
本文详细介绍了如何在Spring项目中引入和配置SpringSecurity,包括SpringBoot和非SpringBoot环境下的依赖管理,以及SpringMVC中Java配置的安全设置。内容涵盖UserDetailsService配置,SecurityFilterChain的注册与定制,多FilterChain配置,自定义DSLs以及对象后处理。
&spm=1001.2101.3001.5002&articleId=110822577&d=1&t=3&u=5cf283c4aba44d11a476f491ec92e4ee)
1万+

被折叠的 条评论
为什么被折叠?



