如何拦截特定的请求
只有满足了SecurityFilterChain的match方法的请求才能被该SecurityFilterChain处理,那如何配置才能让一个SecurityFilterChain处理特定的路径呢?
RequestMatcher
HttpSecurity内置了RequestMatcher属性来处理路径匹配问题。RequestMatcher可总结为以下几大类:
使用Ant路径:
httpSecurity.antMatcher("/foo/**");
如果你配置了全局的Servlet Path的话,例如/v1,配置ant路径的话就要/v1/foo/**,使用MVC风格可以保持一致:
httpSecurity.mvcMatcher("/foo/**");
另外MVC风格可以自动匹配后缀,例如/foo/hello可以匹配/foo/hello.do、/foo/hello.action 等等。另外你也可以使用正则表达式来进行路径匹配:
httpSecurity.regexMatcher("/foo/.+");
如果上面的都满足不了需要的话,你可以通过HttpSecurity.requestMatcher方法自定义匹配规则;如果你想匹配多个规则的话可以借助于HttpSecurity.requestMatchers方法来自由组合匹配规则,就像这样:
httpSecurity.requestMatchers(requestMatchers -> requestMatchers.mvcMatchers("/foo/**") .antMatchers("/admin/*get"));
一旦你配置了路径匹配规则的话,你会发现默认的表单登录404了,因为默认是/login,你加了前缀后当然访问不到了。
使用场景
比如你后台管理系统和前端应用各自走不同的过滤器链,你可以根据访问路径来配置各自的过滤器链。例如:
/** * Admin 过滤器链. * * @param http the http * @return the security filter chain * @throws Exception the exception */ @Bean SecurityFilterChain adminSecurityFilterChain(HttpSecurity http) throws Exception { http.requestMatchers(requestMatchers -> requestMatchers.mvcMatchers("/admin/**")) //todo 其它配置 return http.build(); } /** * App 过滤器链. * * @param http the http * @return the security filter chain * @throws Exception the exception */ @Bean SecurityFilterChain appSecurityFilterChain(HttpSecurity http) throws Exception { http.requestMatchers(requestMatchers -> requestMatchers.mvcMatchers("/app/**")); //todo 其它配置 return http.build(); }
另外也可以使用该特性降低不同规则URI之间的耦合性。
思考一下HttpSecurity这个Spring Bean为什么能够重复使用。