spring-secrity的Filter顺序+自定义过滤器

Filter顺序

Spring Security的官方文档向我们提供了filter的顺序,实际应用中无论用到了哪些,整体的顺序是保持不变的:

  1. ChannelProcessingFilter,重定向到其他协议的过滤器。也就是说如果你访问的channel错了,那首先就会在channel之间进行跳转,如http变为https。
  2. SecurityContextPersistenceFilter,请求来临时在SecurityContextHolder中建立一个SecurityContext,然后在请求结束的时候,清空SecurityContextHolder。并且任何对SecurityContext的改变都可以被copy到HttpSession。
  3. ConcurrentSessionFilter,因为它需要使用SecurityContextHolder的功能,而且更新对应session的最后更新时间,以及通过SessionRegistry获取当前的SessionInformation以检查当前的session是否已经过期,过期则会调用LogoutHandler。
  4. 认证处理机制,如UsernamePasswordAuthenticationFilter,CasAuthenticationFilter,BasicAuthenticationFilter等,以至于SecurityContextHolder可以被更新为包含一个有效的Authentication请求。
  5. SecurityContextHolderAwareRequestFilter,它将会把HttpServletRequest封装成一个继承自HttpServletRequestWrapper的SecurityContextHolderAwareRequestWrapper,同时使用SecurityContext实现了HttpServletRequest中与安全相关的方法。
  6. JaasApiIntegrationFilter,如果SecurityContextHolder中拥有的Authentication是一个JaasAuthenticationToken,那么该Filter将使用包含在JaasAuthenticationToken中的Subject继续执行FilterChain。
  7. RememberMeAuthenticationFilter,如果之前的认证处理机制没有更新SecurityContextHolder,并且用户请求包含了一个Remember-Me对应的cookie,那么一个对应的Authentication将会设给SecurityContextHolder。
  8. AnonymousAuthenticationFilter,如果之前的认证机制都没有更新SecurityContextHolder拥有的Authentication,那么一个AnonymousAuthenticationToken将会设给SecurityContextHolder
  9. ExceptionTransactionFilter,用于处理在FilterChain范围内抛出的AccessDeniedException和AuthenticationException,并把它们转换为对应的Http错误码返回或者对应的页面。
  10. FilterSecurityInterceptor,保护Web URI,进行权限认证,并且在访问被拒绝时抛出异常。

自定义过滤器

       除了这些过滤器外,我们可能还需要在认证链路中自定义一些过滤器。

       oauth2拦截器在初始化完成后,共会生成三个拦截器调用链,分别对应oauth/token等的oauth2认证拦截器调用链,对resource资源访问的拦截器调用链,springsecurity的拦截器调用链。

  1. oauth2认证拦截器调用链

       通过AuthorizationServerSecurityConfigurer的addTokenEndpointAuthenticationFilter()方法我们可以在BasicAuticaitonFilter前加入拦截器。

       这个过滤器是在ClientCredentialsTokenEndpointFilter之后的,所以,如果想在ClientCredentialsTokenEndpointFilter过滤器之前加过滤器的话, 我还没找到方法

  1. spring-secrity的Filter顺序+自定义过滤器_第1张图片
@Configuration
public class OAuth2ServerFilterConfig extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(AuthorizationServerSecurityConfigurer configurer) throws Exception {
        configurer.addTokenEndpointAuthenticationFilter(oauth2JsonClientAuthFilter());
    }

    private Filter oauth2JsonClientAuthFilter() {
        Oauth2JsonClientAuthFilter oauth2JsonClientAuthFilter = new Oauth2JsonClientAuthFilter();
        oauth2JsonClientAuthFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                Authentication authentication) throws IOException, ServletException {

            }
        });
        return oauth2JsonClientAuthFilter;

    }
}  

2. resource资源拦截器调用链

@Configuration
public class AuthResourceServerConfigurer extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        super.configure(resources);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated();
        //这个是对所有url都进行拦截,因为没设置发现只有对部分url生效
        http.requestMatcher(AnyRequestMatcher.INSTANCE);
    }
}

3.springsecurity认证拦截器

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
    //其余代码省略
    http.addFilterBefore(mutiLoginDemoFilter(httpSecurity), BasicAuticaitonFilter.class);
    }
}

这里springsecurity的加入的过滤器都比addTokenEndpointAuthenticationFilter加入的过滤器执行晚,通过代码就可以看出:

public final class HttpSecurity extends
		AbstractConfiguredSecurityBuilder
		implements SecurityBuilder,
		HttpSecurityBuilder {

@Override
	protected DefaultSecurityFilterChain performBuild() {
        //这里获取所有的拦截器,filters.sort(comparator) 将所有的过滤器排序后返回
		filters.sort(comparator);
		return new DefaultSecurityFilterChain(requestMatcher, filters);
	}

}

public HttpSecurity addFilterBefore(Filter filter,
			Class beforeFilter) {
		comparator.registerBefore(filter.getClass(), beforeFilter);
		return addFilter(filter);
	}

你可能感兴趣的:(java,#,spring,#,spring,cloud,spring,java,后端)