对于Spring Security,核心过滤器链可以说是它的核心之一。本文将从什么是核心过滤器链、以及它包含哪些过滤器等方面进行详细讲解。
1. 什么是核心过滤器链?
核心过滤器链是Spring Security运作的基础。当一个请求进来时,它将会被一系列的过滤器处理,处理完成后才会交给真正的应用程序处理。核心过滤器链由一系列的过滤器组成,每个过滤器都有自己的功能和责任。
2. 核心过滤器链包含哪些过滤器?
Spring Security的核心过滤器链由以下过滤器组成:
-
ChannelProcessingFilter
- 它主要负责检查请求是否是从安全渠道(HTTPS)发送来的。如果不是,则拒绝该请求或者将其重定向到HTTPS。 -
SecurityContextPersistenceFilter
- 它的主要作用是在HttpServletRequest中存储Spring Security的SecurityContext。SecurityContext存储了对当前用户的验证信息和授权信息。 -
ConcurrentSessionFilter
- 它负责并发会话控制。如果用户的会话已经被其他人占用,则它将防止用户使用该会话。当然,这个功能是可配置的。 -
LogoutFilter
- 它主要负责用户退出登录时的处理工作,比如清空session、删除cookie等。 -
UsernamePasswordAuthenticationFilter
- 它是用户认证的核心。它接收以POST方式提交的“username”和“password”,并将它们封装成一个UsernamePasswordAuthenticationToken传递给AuthenticationManager进行认证。 -
DefaultLoginPageGeneratingFilter
- 它负责生成默认的登录页面。该过滤器会从当前应用程序的登录页面生成表单,并将它们提供给用户进行登录。 -
BasicAuthenticationFilter
- 它可能是最简单的过滤器之一。它负责基本身份验证。它从HTTP头中提取用户名和密码,并将它们传递给AuthenticationManager进行认证。 -
RequestCacheAwareFilter
- 它负责将请求缓存起来,以便在用户重定向到登录页面后,将请求的原始URL存储在HttpSession中。 -
SecurityContextHolderAwareRequestFilter
- 它负责检查当前请求是否是SECURITY_CONTEXT_ATTRIBUTE设置为NONE的请求。如果是,它将使用SecurityContextHolder来清除安全上下文对象。 -
AnonymousAuthenticationFilter
- 它负责生成匿名Authentication对象,并将其传递给SecurityContextHolder。这个过滤器通常在用户未认证时使用。 -
SessionManagementFilter
- 它负责会话管理,比如会话超时的处理等。 -
ExceptionTranslationFilter
- 它负责在发生认证异常或授权异常时的处理工作。 -
FilterSecurityInterceptor
- 它负责处理URL级别的安全性。它从配置中检索所需的访问级别,并检查当前用户是否具有该访问级别。
3. 核心过滤器链示例
下面是两个基于Spring Security的简单web应用程序的例子:
示例1
- 实现类
org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer
:
```java
package com.example.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
```
- 配置类
com.example.config.WebSecurityConfig
:
```java
package com.example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
}
```
- 实现类
com.example.config.MyUserDetailsService
:
```java
package com.example.config;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.Collections;
@Component
public class MyUserDetailsService implements UserDetailsService {
private final PasswordEncoder encoder;
public MyUserDetailsService() {
this.encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (username.equals("admin")) {
return User.withUsername("admin").password(encoder.encode("123456")).roles(Collections.singletonList("USER")).build();
}
throw new UsernameNotFoundException("User '" + username + "' not found");
}
}
```
示例2
- 实现类
org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer
:
```java
package com.example.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
```
- 配置类
com.example.config.WebSecurityConfig
:
```java
package com.example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest().authenticated().and().formLogin().and().httpBasic();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
}
```
- 控制器类
com.example.controller.PublicController
:
```java
package com.example.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PublicController {
@GetMapping("/public")
public String publicEndpoint() {
return "Hello Public!";
}
}
```
- 控制器类
com.example.controller.SecureController
:
```java
package com.example.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SecureController {
@GetMapping("/secure")
public String secureEndpoint() {
return "Hello Secure!";
}
}
```
通过对两个示例的了解,我们可以初步认识Spring Security核心过滤器链的作用和用法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security 核心过滤器链讲解 - Python技术站