SpringSecurity------引入方式和配置(一)
-
- 1、使用Spring Boot构建
- 2、不使用Spring Boot构建
- 3、Maven 仓库
- 4、Spring MVC使用Spring Security的Java Configuration配置步骤
-
- 4.1 、配置UserDetailsService
- 4.2、注册SecurityFilterChain、引入WebSecurityConfig配置文件
- 4.3、配置SecurityFilterChain
- 4.4、配置多个SecurityFilterChain
- 4.5、自定义DSLs
- 4.6、Post Processing Configured Objects
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 {
@Beanpublic 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 SecurityWebApplicationInitializerextends AbstractSecurityWebApplicationInitializer {
//开启 HttpSessionEventPublisher@Overrideprotected boolean enableHttpSessionEventPublisher() {
return true;}// ... other overrides ...
}
public class MvcWebApplicationInitializer extendsAbstractAnnotationConfigDispatcherServletInitializer {
@Overrideprotected 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 {
//创建一个用户名密码加载器@Beanpublic 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指定排序的拦截器默认是最后执行@Beanpublic 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;@Overridepublic void init(HttpSecurity http) throws Exception {
//添加任何其他配置器都需要在这个init方法中http.csrf().disable();}@Overridepublic 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 {
@Beanpublic 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 {
@Beanpublic 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();
}
下一篇:SpringSecurity------密码存储(二)