ITPub博客

首页 > 数据库 > 数据库开发技术 > SpringSecurity HttpSecurity 默认过滤器

SpringSecurity HttpSecurity 默认过滤器

原创 数据库开发技术 作者:DevXTalk 时间:2024-01-05 08:30:00 0 删除 编辑

SpringSecurity HttpSecurity 默认过滤器

  • DisabledEncodeUrlFilter
  • WebAsyncManagerIntegrationFilter
  • HeaderWriterFilter
  • CsrfFilter
  • LogoutFilter
  • RequestCacheAwareFilter
  • SecurityContextHolderAwareRequestFilter
  • AnonymousAuthenticationFilter
  • ExceptionTranslationFilter

DisabledEncodeUrlFilter:阻止将sessionId写到url中,防止由于http请求的访问日志导致Session泄露。

❝
  • 先使用装饰者模式,通过继承HttpServletResponseWrapper将response包装起来,然后将包装后的对象作为response走过滤器链的下面过程
  • 继承的目的是重写response相关的encodeUrl相关的方法,原样返回url(取消将sessionId写到url)
❞
  • WebAsyncManagerIntegrationFilter:异步执行之前将SpringContext塞进去
❝

Spring Web中有一个WebAsyncManager可允许我们的请求是异步执行的,如果请求是异步处理请求肯定会启动一个新的线程。如果想要在异步的线程中获取SecurityContext肯定是不行的。因为默认的SpringContextHodler持有的SecurityContextHolderStrategy是基于ThreadLocal的。

❞
❝

通过提前使用springmvc的WebAsyncUtils获取WebAsyncManager,来往里面注册SecurityContextCallableProcessingInterceptor拦截器,这个拦截器会在异步线程池提交任务前从SecurityContextHolder中获取SecurityContext,在callable任务执行call方法前,将提前获取的SecurityContext设置到当前线程中,保证在异步请求中也能拿到SecurityContext

❞
protected void WebAsyncManagerIntegrationFilter#doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 在执行异步之前会执行一堆的拦截器
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
SecurityContextCallableProcessingInterceptor securityProcessingInterceptor = (SecurityContextCallableProcessingInterceptor) asyncManager
.getCallableInterceptor(CALLABLE_INTERCEPTOR_KEY);
if (securityProcessingInterceptor == null) {
// 向WebAsyncManager注册SecurityContextCallableProcessingInterceptor拦截器
asyncManager.registerCallableInterceptor(CALLABLE_INTERCEPTOR_KEY,
new SecurityContextCallableProcessingInterceptor());
}
filterChain.doFilter(request, response);
}

SecurityContextCallableProcessingInterceptor:在异步方法执行前,将当前持有的securityContext放到异步线程中

@Override
public <T> void preProcess(NativeWebRequest request, Callable<T> task) {
SecurityContextHolder.setContext(this.securityContext);
}

@Override
public <T> void postProcess(NativeWebRequest request, Callable<T> task, Object concurrentResult) {
SecurityContextHolder.clearContext();
}

HeaderWriterFilter:写响应头,通过委托把将写响应头的工作交给维护的一堆HeaderWraiter去实现

CsrfFilter:防止跨站请求伪造

❝
  • 默认只处理非"GET", "HEAD", "TRACE", "OPTIONS"的请求
  • 里面使用CsrfTokenRepository保存csrfToken,默认实现是HttpSessionCsrfTokenRepository,将csrfToken存入HttpSession中
  • 从请求头或者请求参数中获取到的csrfToken值与保存的csrfToken值必须相同,才会放行到下一个过滤器,来防止跨站请求伪造(就算拿了JESESSIONID,没有csrf的请求参数(_csrf)或头(X-XSRF-TOKEN)与后端不一致,也请求不了)
❞

LogoutFilter

❝
  • 默认处理退出登录的路径是/logout(可以自定义),退出登录的具体逻辑委托给自身的LogoutHandler处理器(组合模式,可组合多个退出登录的处理器,比如销毁会话、清空SecurityContext、发布退出成功事件),退出成功后,由logoutSuccessHandler处理,然后直接return停止过滤器的执行。
❞

RequestCacheAwareFilter

❝
  • 用户未经过认证访问某个url时,保存此请求对象,默认通过保存到HttpSession实现。
  • 而当用户登录成功后,将之前保存的请求对象放入过滤器链中执行
❞

SecurityContextHolderAwareRequestFilter

❝
  • 通过HttpServletRequestFactory将HttpServletRequest请求包装成SecurityContextHolderAwareRequestWrapper,实现了getUserPrincipal()、getRemoteUser()等,这些方法会直接从SecurityContext获取认证对象中的用户信息,这样就可以直接调用request#getUserPrincipal()获取对应的用户信息。
❞

AnonymousAuthenticationFilter

❝
  • 当SecurityContex中没有Authentication时,会创建出一个AnonymousAuthenticationToken的Authentication对象(principals属性默认为"anonymousUser",authorities属性默认为"ROLE_ANONYMOUS")
  • SpringSecurity中将用户分为登录的和未登录的,未登录的就是匿名用户,登录的又分为认证的(可能通过rememberMe的方式登录)和完全认证的(通过UsernamePassword完全登录)
❞

ExceptionTranslationFilter

❝
  • 位于FilterSecurityInterceptor过滤器之前,对后面filterChain.doFilter(..)进行了try-catch,并使用throwableAnalyzer分析抛出的异常,对security中的2种异常:AuthenticationException(认证异常,一般重定向到认证入口)、AccessDeniedException(访问拒绝-未完全认证或权限不够)做处理
❞

欢迎加入 DevXTalk 的技术交流群,在这里你可以和大佬们一起交流分享技术,行业经验,提升自我。 结识新的业内朋友,扩大自己的圈子,当你想换工作的时候也许就能拿到不错的 offer 。总之期待你的加入...


「看完本文有收获?转发给更多的朋友吧」

「DevXTalk 不止于技术」

原文作者:DevXTalk;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2019-03-23

  • 博文量
    178
  • 访问量
    82579