Spring Filter FilterRegistrationBean 能否使用正则表达式拦截请求
文章目录
起因
最近有需求需要把站点的所有请求做一次XSS过滤,第一反应就是用Filter来做一次入参过滤(历史原因在Spring中做比在前端处理要容易),而且需要自由设置某些路由不做过滤,所以先加了一个注解@XxsFilter
,有注解的路由会经过XssFilter过滤,没有注解的不做处理。
事故
做完之后发现翻车了。
想到的思路是在注入FilterRegistrationBean
时通过遍历RequestMappingHandlerMapping
的HandlerMethod
来找到所有加了自定义注解@XxsFilter
的路由,将路由参数通过FilterRegistrationBean
的addUrlPatterns
添加进拦截规则中。
规则添加没有问题,出问题的是一些路由中带有PathVariable
的路由无法被正常拦截,如/item/{id}/info
这种路由。
历程
因为知识点不扎实,第一反应是之前使用Filter在addUrlPatterns
时候都是直接添加/*
、*.css
之类的,所以直接将{id}
替换成*
或者\D+
之类的正则就可以了。
然而,事实确实完全不会生效。
一通百度(公司的网梯子偶尔访问不到),全网基本都是教怎么添加/*
、*.css
,就和整个中文世界没有人尝试在Filter中设置正则路由拦截一样,晚上在家里Google了一下,先看到了Can i use wildcard for path variable in spring webfilter?。
文章中提到Spring的PathMatch都是用的https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/util/AntPathMatcher.html,然后百般尝试,发现还是不行,答主Chandan完全是没有经过尝试只是想当然的回答。
结局
多翻了几个链接后,终于在Can we use regular expressions in web.xml URL patterns?这里看到正确答案,Filter中虽然有*
这种用法,但是并不是一个正则表达式,而且Filter也并不支持使用正则表达式拦截请求。
如果需要拦截就只能在doFilter
通过request.getRequestURI()
获取到当前访问的URI,再通过正则表达式自行过滤,但这样如果和我最初的需求:部分路由需要过滤,就会有一些出入。
按我的需求,只能遍历所有带有@XxsFilter
的路由放入一个数组,然后遍历整个数组,再通过正则匹配每个请求的request.getRequestURI()
来判断是否需要进行Xss过滤。
性能损失太大了,这种思路只能放弃。
附送另外一个知识点
How do I enable a filter for url that includes a certain word?这个问题中有提到Filter(过滤器)和Interceptor(拦截器)的区别:
过滤器可以修改入参,并将修改后的入参传递给后续的步骤继续处理,而拦截器不可以
文章作者 P.X.C
上次更新 2020-07-19
许可协议 不允许任何形式转载。