Filter在SecurityFilterChain上的的排序规则

为了让系统正常运行,SecurityFilterChain 上的Filter要保持一定的顺序,例如AuthorizationFilter 要放在各类AuthenticationFilter 的后面,不然还没认证就开始校验权限信息,那一定不会通过。

Spring Security为默认的Filter设置了固定的顺序,这些Filter和Filter的子类,都会按照这个顺序执行。

重要限制

所有Filter都要设置顺序值,可以使用HttpSecurity 的 addFilterAfter(Filter filter, Class<? extends Filter> afterFilter) 和addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter) 方法来添加Filter,方法的第二个参数就是下面默认的Filter类型。

Filter默认顺序

Spring Security在FilterOrderRegistration类中设置了Filter类型的默认顺序。然后在添加Filter时,会根据Filter类型获取Order。

设置顺序是在构造函数实现,获取顺序是在getOrder(Class<?> clazz)方法,会根据Filter类型或父类型找到顺序值。

FilterOrderRegistration() {
	// INITIAL_ORDER、ORDER_STEP值默认为100
	Step order = new Step(INITIAL_ORDER, ORDER_STEP);
	// order.next()会返回当前order,并且把order增加step大小
	put(DisableEncodeUrlFilter.class, order.next());
	put(ForceEagerSessionCreationFilter.class, order.next());
	put(ChannelProcessingFilter.class, order.next());
	order.next(); // gh-8105
	put(WebAsyncManagerIntegrationFilter.class, order.next());
	put(SecurityContextHolderFilter.class, order.next());
	put(SecurityContextPersistenceFilter.class, order.next());
	put(HeaderWriterFilter.class, order.next());
	put(CorsFilter.class, order.next());
	put(CsrfFilter.class, order.next());
	put(LogoutFilter.class, order.next());
	this.filterToOrder.put(
			"org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter",
			order.next());
	this.filterToOrder.put(
			"org.springframework.security.saml2.provider.service.web.Saml2WebSsoAuthenticationRequestFilter",
			order.next());
	put(X509AuthenticationFilter.class, order.next());
	put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
	this.filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter", order.next());
	this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter",
			order.next());
	this.filterToOrder.put(
			"org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter",
			order.next());
	put(UsernamePasswordAuthenticationFilter.class, order.next());
	order.next(); // gh-8105
	put(DefaultLoginPageGeneratingFilter.class, order.next());
	put(DefaultLogoutPageGeneratingFilter.class, order.next());
	put(ConcurrentSessionFilter.class, order.next());
	put(DigestAuthenticationFilter.class, order.next());
	this.filterToOrder.put(
			"org.springframework.security.oauth2.server.resource.web.authentication.BearerTokenAuthenticationFilter",
			order.next());
	put(BasicAuthenticationFilter.class, order.next());
	put(RequestCacheAwareFilter.class, order.next());
	put(SecurityContextHolderAwareRequestFilter.class, order.next());
	put(JaasApiIntegrationFilter.class, order.next());
	put(RememberMeAuthenticationFilter.class, order.next());
	put(AnonymousAuthenticationFilter.class, order.next());
	this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter",
			order.next());
	put(SessionManagementFilter.class, order.next());
	put(ExceptionTranslationFilter.class, order.next());
	put(FilterSecurityInterceptor.class, order.next());
	put(AuthorizationFilter.class, order.next());
	put(SwitchUserFilter.class, order.next());
}

Integer getOrder(Class<?> clazz) {
	while (clazz != null) {
		Integer result = this.filterToOrder.get(clazz.getName());
		if (result != null) {
			return result;
		}
		clazz = clazz.getSuperclass();
	}
	return null;
}

排序规则

在把Filter添加到SecurityFilterChain之前,会对所有Filter进行排序。排序使用OrderComparator类提供的规则:

  1. Filter是PriorityOrdered的子类,那么排在最前面

  1. Filter的Ordered值越小,排名越靠前

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李昂的数字之旅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值