在Spring Security的配置流程里,请求携带token时,会先执行 addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
所添加的过滤器,之后再进行 authorizeHttpRequests
里的权限判断,下面为你详细解释:
1. 过滤器链的执行顺序
Spring Security是基于过滤器链来处理请求的。在配置中通过 addFilterBefore
添加的过滤器会按照配置的顺序插入到过滤器链中。authenticationTokenFilter
通常用于解析请求头中的token,验证其有效性,并且将用户信息加载到Spring Security的上下文里。
UsernamePasswordAuthenticationFilter
是Spring Security默认用于处理表单登录的过滤器。当你使用 addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
时,意味着 authenticationTokenFilter
会在 UsernamePasswordAuthenticationFilter
之前执行。
2. 权限判断的时机
authorizeHttpRequests
方法用于配置请求的访问规则,这些规则是在过滤器链执行完成之后才进行判断的。也就是说,在请求经过一系列过滤器(包含 authenticationTokenFilter
)处理之后,才会依据 authorizeHttpRequests
中配置的规则来判断该请求是否被允许访问。
3. 执行流程示例
以下是一个简化的执行流程:
- 请求进入:客户端发送携带token的请求到服务器。
- 过滤器链执行:请求首先进入
authenticationTokenFilter
,该过滤器会从请求头中提取token,对其进行验证,若验证通过,就会将用户信息加载到Spring Security的上下文里。 - 其他过滤器处理:请求继续通过过滤器链中的其他过滤器进行处理。
- 权限判断:当请求通过所有过滤器之后,会依据
authorizeHttpRequests
中配置的规则进行权限判断。若请求的URL匹配到permitAll
的规则,那么请求会被允许访问;若匹配到authenticated
规则,就会检查Spring Security上下文中是否存在有效的认证信息,若存在则允许访问,反之则拒绝访问。
4. 代码示例说明
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.annotation.Resource;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Resource
private JwtAuthenticationTokenFilter authenticationTokenFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// 关闭csrf
.csrf().disable()
// 不通过Session获取SecurityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeHttpRequests((requests) -> {
// 允许匿名访问的URL列表
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
requests.antMatchers("/login", "/system/device/deviceData", "/register", "/captchaImage").permitAll()
.antMatchers("/system/category/**").permitAll()
// 静态资源,可匿名访问
.antMatchers(org.springframework.http.HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
});
return http.build();
}
}
在这个配置中,authenticationTokenFilter
会在 UsernamePasswordAuthenticationFilter
之前执行,之后才会进行 authorizeHttpRequests
中的权限判断。
综上所述,携带token的请求会先经过 addFilterBefore
添加的过滤器,然后再进行 authorizeHttpRequests
中的权限判断。