SpringSecurity - 启动流程分析(四)- 默认过滤器


活动地址:CSDN21天学习挑战赛

前言

SpringSecurity - 启动流程分析(三) 这篇文章的最后,我们知道了 SpringSecurity 最后会在 ApplicationFilterConfig 中加入一个名为 springSecurityFilterChainFilter

在这里插入图片描述

其中包含了 SpringSecurity 默认提供的 12 个过滤器:

在这里插入图片描述

同时我们也可以看到 FilterChains 中只有一个 DefaultSecurityFilterChain,这里贴一下源码:

// security 的 Filter 排序规则
private FilterComparator comparator = new FilterComparator();

@Override
protected DefaultSecurityFilterChain performBuild() {
	// 排序
	filters.sort(comparator);
	return new DefaultSecurityFilterChain(requestMatcher, filters);
}

看一下 FilterComparator 的源码:

final class FilterComparator implements Comparator<Filter>, Serializable {
	// 初始顺序值为100
	private static final int INITIAL_ORDER = 100;
	// 步长为100
	private static final int ORDER_STEP = 100;
	private final Map<String, Integer> filterToOrder = new HashMap<>();

	FilterComparator() {
		Step order = new Step(INITIAL_ORDER, ORDER_STEP);
		put(ChannelProcessingFilter.class, order.next());
		put(ConcurrentSessionFilter.class, order.next());
		put(WebAsyncManagerIntegrationFilter.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());
		filterToOrder.put(
			"org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter",
				order.next());
		filterToOrder.put(
				"org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter",
				order.next());
		put(X509AuthenticationFilter.class, order.next());
		put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
		filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter",
				order.next());
		filterToOrder.put(
			"org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter",
				order.next());
		filterToOrder.put(
				"org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter",
				order.next());
		put(UsernamePasswordAuthenticationFilter.class, order.next());
		put(ConcurrentSessionFilter.class, order.next());
		filterToOrder.put(
				"org.springframework.security.openid.OpenIDAuthenticationFilter", order.next());
		put(DefaultLoginPageGeneratingFilter.class, order.next());
		put(DefaultLogoutPageGeneratingFilter.class, order.next());
		put(ConcurrentSessionFilter.class, order.next());
		put(DigestAuthenticationFilter.class, order.next());
		filterToOrder.put(
				"org.springframework.security.oauth2.server.resource.web.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());
		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(SwitchUserFilter.class, order.next());
	}
	...
}

这里定义了 SpringSecurity 提供的默认过滤器的执行顺序。

分析

下面我们就按照上面给出的执行顺序看一下这些默认的 Filters,由于这里的 Filter 比较多,所以这里就只是简单介绍一下每一个 Filter 的作用,重要的 Filter 后面再通过几篇文章重点说,比如 UsernamePasswordAuthenticationFilter

1、WebAsyncManagerIntegrationFilter

/**
 * Provides integration between the {@link SecurityContext} and Spring Web's
 * {@link WebAsyncManager} by using the
 * {@link SecurityContextCallableProcessingInterceptor#beforeConcurrentHandling(org.springframework.web.context.request.NativeWebRequest, Callable)}
 * to populate the {@link SecurityContext} on the {@link Callable}.
 */
public final class WebAsyncManagerIntegrationFilter extends OncePerRequestFilter {}

从源码注释中可以看出,该 Filter 的作用提供了 SecurityContextSpring WebWebAsyncManager 的集成,处理在异步线程中的 SecurityContext

2、SecurityContextPersistenceFilter

/**
 * Populates the {@link SecurityContextHolder} with information obtained from the
 * configured {@link SecurityContextRepository} prior to the request and stores it back in
 * the repository once the request has completed and clearing the context holder. By
 * default it uses an {@link HttpSessionSecurityContextRepository}. See this class for
 * information <tt>HttpSession</tt> related configuration options.
 */
public class SecurityContextPersistenceFilter extends GenericFilterBean {}

Filter 的主要作用是为了加载 SecurityContextSecurityContextHolder 中,从命名中就可以看出来(Spring 的命名很是严谨,一般都可以见名知意)。

3、HeaderWriterFilter

/**
 * Filter implementation to add headers to the current response. Can be useful to add
 * certain headers which enable browser protection. Like X-Frame-Options, X-XSS-Protection
 * and X-Content-Type-Options.
 */
public class HeaderWriterFilter extends OncePerRequestFilter {}

Filter 的作用主要是对响应信息的请求头添加一些配置

4、CsrfFilter

/**
 * <p>
 * Applies
 * <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)" >CSRF</a>
 * protection using a synchronizer token pattern. Developers are required to ensure that
 * {@link CsrfFilter} is invoked for any request that allows state to change. Typically
 * this just means that they should ensure their web application follows proper REST
 * semantics (i.e. do not change state with the HTTP methods GET, HEAD, TRACE, OPTIONS).
 * </p>
 */
public final class CsrfFilter extends OncePerRequestFilter {}

Filter 的作用主要是防止跨站请求伪造

5、LogoutFilter

/**
 * Logs a principal out.
 * <p>
 * Polls a series of {@link LogoutHandler}s. The handlers should be specified in the order
 * they are required. Generally you will want to call logout handlers
 * <code>TokenBasedRememberMeServices</code> and <code>SecurityContextLogoutHandler</code>
 * (in that order).
 * <p>
 * After logout, a redirect will be performed to the URL determined by either the
 * configured <tt>LogoutSuccessHandler</tt> or the <tt>logoutSuccessUrl</tt>, depending on
 * which constructor was used.
 */
public class LogoutFilter extends GenericFilterBean {}

Filter 的作用主要是对登出操作做处理,我们可以自定义 LogoutHandles 来处理登出逻辑,并且可以配置 LogoutSuccessHandle 或者指定 logoutSuccessUrl

6、UsernamePasswordAuthenticationFilter

/**
 * Processes an authentication form submission. Called
 * {@code AuthenticationProcessingFilter} prior to Spring Security 3.0.
 * <p>
 * Login forms must present two parameters to this filter: a username and password. The
 * default parameter names to use are contained in the static fields
 * {@link #SPRING_SECURITY_FORM_USERNAME_KEY} and
 * {@link #SPRING_SECURITY_FORM_PASSWORD_KEY}. The parameter names can also be changed by
 * setting the {@code usernameParameter} and {@code passwordParameter} properties.
 * <p>
 * This filter by default responds to the URL {@code /login}.
 */
public class UsernamePasswordAuthenticationFilter extends
		AbstractAuthenticationProcessingFilter {}

Filter 的作用是处理默认的 /login 请求,也是 SpringSecurity 提供的默认用户密码登录认证,后面会详细分析该 Filter

7、RequestCacheAwareFilter

/**
 * Responsible for reconstituting the saved request if one is cached and it matches the
 * current request.
 * <p>
 * It will call
 * {@link RequestCache#getMatchingRequest(HttpServletRequest, HttpServletResponse)
 * getMatchingRequest} on the configured <tt>RequestCache</tt>. If the method returns a
 * value (a wrapper of the saved request), it will pass this to the filter chain's
 * <tt>doFilter</tt> method. If null is returned by the cache, the original request is
 * used and the filter has no effect.
 */
public class RequestCacheAwareFilter extends GenericFilterBean {}

Filter 的作用是用于用户登录成功后,重新恢复跳转到登录之前的请求

8、SecurityContextHolderAwareRequestFilter

/**
 * A <code>Filter</code> which populates the <code>ServletRequest</code> with a request
 * wrapper which implements the servlet API security methods.
 * <p>
 * {@link SecurityContextHolderAwareRequestWrapper} is extended to provide the following
 * additional methods:
 * </p>
 */
public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {}

Filter 的作用是拓展了 HttpServletRequest,在每一个请求中添加了一些额外的方法,比如:getPrincipal() 方法。可以在任何地方获取 SecurityContext

9、AnonymousAuthenticationFilter

/**
 * Detects if there is no {@code Authentication} object in the
 * {@code SecurityContextHolder}, and populates it with one if needed.
 */
public class AnonymousAuthenticationFilter extends GenericFilterBean implements
		InitializingBean {}

Filter 的作用是对匿名用户做一些处理,比如:设置 principalauthorities

10、SessionManagementFilter

/**
 * Detects that a user has been authenticated since the start of the request and, if they
 * have, calls the configured {@link SessionAuthenticationStrategy} to perform any
 * session-related activity such as activating session-fixation protection mechanisms or
 * checking for multiple concurrent logins.
 */
public class SessionManagementFilter extends GenericFilterBean {}

Filter 的作用是管理 Session

11、ExceptionTranslationFilter

/**
 * Handles any <code>AccessDeniedException</code> and <code>AuthenticationException</code>
 * thrown within the filter chain.
 * <p>
 * This filter is necessary because it provides the bridge between Java exceptions and
 * HTTP responses. It is solely concerned with maintaining the user interface. This filter
 * does not do any actual security enforcement.
 */
public class ExceptionTranslationFilter extends GenericFilterBean {}

Filter 的作用是对于任意的 AccessDeniedException 类型的异常和 AuthenticationException 类型异常的处理

12、FilterSecurityInterceptor

/**
 * Performs security handling of HTTP resources via a filter implementation.
 * <p>
 * The <code>SecurityMetadataSource</code> required by this security interceptor is of
 * type {@link FilterInvocationSecurityMetadataSource}.
 * <p>
 * Refer to {@link AbstractSecurityInterceptor} for details on the workflow.
 * </p>
 */
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements
		Filter {}

Filter 的作用主要是做认证和授权拦截,比如我们配置了对某个 url 限制某种角色能够访问,就是在这里进行鉴权,判断是否放行

总结

以上就是基于 SpringSecurity 5.3.9.RELEASE 对默认 Filters 的简单分析,目前还不具备详细分析每一个 Filter 实现过程的能力,还有一些概念需要了解,后面会在 SpringSecurity 学习 专栏中对一些重要的 Filter 展开讨论

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值