Spring Security之默认的过滤器链及自定义Filter操作
作者:咸鱼最牛逼 发布时间:2023-11-24 02:48:35
标签:Spring,Security,过滤器链,Filter
Spring Security 过滤器链及自定义Filter
别名 | 类名称 | Namespace Element or Attribute |
---|---|---|
CHANNEL_FILTER | ChannelProcessingFilter | http/intercept-url@requires-channel |
SECURITY_CONTEXT_FILTER | SecurityContextPersistenceFilter | http |
CONCURRENT_SESSION_FILTER | ConcurrentSessionFilter | session-management/concurrency-control |
HEADERS_FILTER | HeaderWriterFilter | http/headers |
CSRF_FILTER | CsrfFilter | http/csrf |
LOGOUT_FILTER | LogoutFilter | http/logout |
X509_FILTER | X509AuthenticationFilter | http/x509 |
PRE_AUTH_FILTER | AbstractPreAuthenticatedProcessingFilter( Subclasses) | N/A |
CAS_FILTER | CasAuthenticationFilter | N/A |
FORM_LOGIN_FILTER | UsernamePasswordAuthenticationFilter | http/form-login |
BASIC_AUTH_FILTER | BasicAuthenticationFilter | http/http-basic |
SERVLET_API_SUPPORT_FILTER | SecurityContextHolderAwareRequestFilter | http/@servlet-api-provision |
JAAS_API_SUPPORT_FILTER | JaasApiIntegrationFilter | http/@jaas-api-provision |
REMEMBER_ME_FILTER | RememberMeAuthenticationFilter | http/remember-me |
ANONYMOUS_FILTER | AnonymousAuthenticationFilter | http/anonymous |
SESSION_MANAGEMENT_FILTER | SessionManagementFilter | session-management |
EXCEPTION_TRANSLATION_FILTER | ExceptionTranslationFilter | http |
FILTER_SECURITY_INTERCEPTOR | FilterSecurityInterceptor | http |
SWITCH_USER_FILTER | SwitchUserFilter | N/A |
过滤器顺序从上到下
自定义 Filter
自定义的 Filter 建议继承 GenericFilterBean,本文示例:
package com.example.filter;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* @author 咸鱼
* @date 2019-05-26 18:02
*/
public class BeforeLoginFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("在 UsernamePasswordAuthenticationFilter 前调用");
chain.doFilter(request, response);
}
}
配置自定义 Filter 在 Spring Security 过滤器链中的位置
配置很简单,本文示例:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/user/**").hasAuthority("USER")
.and()
.formLogin().loginPage("/login").defaultSuccessUrl("/user")
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/login");
// 在 UsernamePasswordAuthenticationFilter 前添加 BeforeLoginFilter
http.addFilterBefore(new BeforeLoginFilter(), UsernamePasswordAuthenticationFilter.class);
// 在 CsrfFilter 后添加 AfterCsrfFilter
http.addFilterAfter(new AfterCsrfFilter(), CsrfFilter.class);
}
说明:
HttpSecurity 有三个常用方法来配置:
addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter)
在 beforeFilter 之前添加 filter
addFilterAfter(Filter filter, Class<? extends Filter> afterFilter)
在 afterFilter 之后添加 filter
addFilterAt(Filter filter, Class<? extends Filter> atFilter)
在 atFilter 相同位置添加 filter, 此 filter 不覆盖 filter
通过在不同 Filter 的 doFilter() 方法中加断点调试,可以判断哪个 filter 先执行,从而判断 filter 的执行顺序 。
spring security添加自定义过滤器
1、定义自己的过滤器
2、指定位置,通过HttpSecurity的方法指定
定义过滤器
package com.qiudaozhang.springsecurity.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestHeadCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
var httpRequest = (HttpServletRequest) servletRequest;
var httpResponse = (HttpServletResponse) servletResponse;
String requestId = httpRequest.getHeader("Request-id");
if(requestId == null || requestId.isBlank()) {
httpResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
filterChain.doFilter(servletRequest,servletResponse);
}
}
package com.qiudaozhang.springsecurity.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestParamCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
var httpRequest = (HttpServletRequest) servletRequest;
var httpResponse = (HttpServletResponse) servletResponse;
String timestamp = httpRequest.getParameter("timestamp");
if(timestamp == null || timestamp.isBlank()) {
httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
filterChain.doFilter(servletRequest,servletResponse);
}
}
指定位置
HttpSecurity中有两个方法,指定过滤器的位置,一个指定在谁前面,一个指定在谁后面。
public HttpSecurity addFilterAfter(Filter filter, Class<? extends Filter> afterFilter) {
this.comparator.registerAfter(filter.getClass(), afterFilter);
return this.addFilter(filter);
}
public HttpSecurity addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter) {
this.comparator.registerBefore(filter.getClass(), beforeFilter);
return this.addFilter(filter);
}
package com.qiudaozhang.springsecurity.config;
import com.qiudaozhang.springsecurity.filter.RequestHeadCheckFilter;
import com.qiudaozhang.springsecurity.filter.RequestParamCheckFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(
new RequestHeadCheckFilter(),
BasicAuthenticationFilter.class
)
.addFilterAfter(new RequestParamCheckFilter(),BasicAuthenticationFilter.class)
.authorizeRequests()
.anyRequest()
.permitAll();
}
}
测试
准备一个端点测试
package com.qiudaozhang.springsecurity.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("hello")
public String hello () {
return "hello";
}
}
当前没有传递timestamp参数,所以参照约定,过滤器直接给出403.
当前头部信息和参数信息都提供了,检测通过。
实际应用场景 检测相关的头部,参数等等信息日志过滤器,将所有请求的相关数据记录下来特殊的权限校验等等。
来源:https://blog.csdn.net/panchang199266/article/details/90578947


猜你喜欢
- 前言这篇文章探索一下springboot的tomcat是如何实现的一、起步依赖1.首先我们了解一下起步依赖SpringBoot结合Maven
- 导读本文主体为单项链表和双向链表的反转以及简单的测试,以便于理解链表相关的算法题目。链表特点便于增删数据,不便于寻址在内存中属于跳转结构单链
- 1)首先启动hadoop2个进程,进入hadoop/sbin目录下,依次启动如下命令[root@node02 sbin]# pwd/usr/
- 1、产生原因其实显示黑屏或者白屏实属正常,这是因为还没加载到布局文件,就已经显示了window窗口背景,黑屏白屏就是window窗口背景。示
- 方案一: 采用reflections 框架(此框架依赖com.google.guava)1、reflections框架地址:https://
- 阿里云accessID和secret请自行进入阿里云申请sms.template.code请进入阿里云,进行短信服务进行魔板添加开源代码地址
- Android 2.3提供一个称为严苛模式StrictMode的调试特性,Google称该特性已经使数百个Android上的Google应用
- 概述Kryo 是一个快速序列化/反序列化工具,依赖于字节码生成机制(底层使用了 ASM 库),因此在序列化速度上有一定的优势,但正因如此,其
- 一、需求有时候应用需要在内部切换语言但又不影响系统的语言,比如是应用现在是中文的,系统语言也是中文的,我把应用的切换成英文显示后系统语言还是
- 一、简介1、DES 简介DES 全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,197
- SpringCloud Gateway 简介SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基
- 今天有朋友问我一道面试题,有5个人抢5个红包,可重复抢,用多线程程序实现,实现方式有多种,分享一下我的思路:应用了阻塞队列的特性。/**
- c# 轮询算法这两天做东西,业务上有个特殊的需求,在用户访问页面的时候,针对某一行代码进行控制,按照概率来进行显示,我做的是针对当前页面的曝
- 使用开源框架是,可以直接复制源代码到自己的项目(本人在Android Studio中操作报R程序包不存在),也可以使用jar包,下面记录一下
- 1.简单计算器使用AWT编程,FrameNORTH区域放置TextField组件,将指定为4行5列GridLayout布局管理器的Panel
- Kotlin 基础教程之类、对象、接口Kotlin中类、接口相关概念与Java一样,包括类名、属性、方法、继承等,如下示例:interfac
- Jfreechart本身不能生成SVG图形,但是可以借助另外一个东西,辅助生成.好像是这个:batik ,具体代码请看下文一:Java生成s
- 一、背景有些业务场景下需要将 Java Bean 转成 Map 再使用。以为很简单场景,但是坑很多。二、那些坑2.0 测试对象import
- 笔者前段时间在做react-native开发,一直是有线连接安卓真机进行调试的。有线调试确实带来诸多麻烦,因为在调试过程中需要频繁和手机进行
- 为什么说是常见问题整合呢,因为小编我就是Genymotion模板器最悲剧的使用者,该见过的问题,我基本都见过了,在此总结出这血的教训,望大家