Spring security 自定义多条过滤链
自定义过滤链
Spring security可以通过自定义SecurityFilterChain对象来完成对不同请求url进行不同逻辑的访问控制。
定义一个过滤链
@EnableWebSecurity
public class DefaultSecurityConfig {
@Bean
@Order(1)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http, UserDetailsService userDetailsService) throws Exception {
http
.requestMatchers().antMatchers("/abc")
.and()
.authorizeRequests(authorizeRequests ->
.authorizeRequests.antMatchers("/userinfo/**")
.permitAll()
.anyRequest()
.authenticated()
);
return http.build();
}
这样,一个简单的SecurityFilterChain过滤链就创建成功了。
对于请求路径/abc,会使用次过滤链中的。如果请求中匹配到/userinfo/**的路径,不会进行认证。
Spring如何使用过滤链
Spring security 创建完所有的过滤链后,会为FilterChainProxy对象中filterChains属性进行赋值。
当有请求时,会先获取过滤链。
private List<Filter> getFilters(HttpServletRequest request) {
int count = 0;
for (SecurityFilterChain chain : this.filterChains) {
if (logger.isTraceEnabled()) {
logger.trace(LogMessage.format("Trying to match request against %s (%d/%d)", chain, ++count,
this.filterChains.size()));
}
if (chain.matches(request)) {
return chain.getFilters();
}
}
return null;
}
可以看到,通过fiilterChain的requestMatchers方法进行区分。
如果成功匹配到,则使用当前的过滤链。
相同请求路径的过滤链会匹配到最全面的filterChian,这就是@Order的作用。
如果requestMatchers不配置,会默认所有的请求都走当前过滤链。所有多个过滤链时,一定要根据实际路径进行配置,否则只会有有一条过滤链有效。