(收藏)Spring Security笔记:解决CsrfFilter与Rest服务Post方式的矛盾

标签: 收藏 spring security | 发表时间:2016-12-17 22:14 | 作者:
出处:http://jackyrong.iteye.com
基于Spring Security+Spring MVC的web应用,为了防止跨站提交攻击,通常会配置csrf,即:

1     <http ...>
2         ...
3         <csrf />       
4     </http>
如果应用中有Post方式访问的Rest服务(参考下面的代码),会很不幸的发现,所有POST方式请求的服务会调用失败。

复制代码
1     @RequestMapping(value = "/user/create", method = RequestMethod.POST)
2     @ResponseBody
3     public UserInfo createUser(@RequestBody(required = true) UserInfo user,
4             HttpServletRequest request, HttpServletResponse response)
5             throws Exception {
6         ...
7     }
复制代码
原因在于:启用csrf后,所有http请求都被会CsrfFilter拦截,而CsrfFilter中有一个私有类DefaultRequiresCsrfMatcher

复制代码
1     private static final class DefaultRequiresCsrfMatcher implements RequestMatcher {
2         private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
3
4         /* (non-Javadoc)
5          * @see org.springframework.security.web.util.matcher.RequestMatcher#matches(javax.servlet.http.HttpServletRequest)
6          */
7         public boolean matches(HttpServletRequest request) {
8             return !allowedMethods.matcher(request.getMethod()).matches();
9         }
10     }
复制代码
从这段源码可以发现,POST方法被排除在外了,也就是说只有GET|HEAD|TRACE|OPTIONS这4类方法会被放行,其它Method的http请求,都要验证_csrf的token是否正确,而通常post方式调用rest服务时,又没有_csrf的token,所以校验失败。

解决方法:自己弄一个Matcher

复制代码
1 package com.cnblogs.yjmyzz.utils;
2
3 import java.util.List;
4 import java.util.regex.Pattern;
5
6 import javax.servlet.http.HttpServletRequest;
7
8 import org.springframework.security.web.util.matcher.RequestMatcher;
9
10 public class CsrfSecurityRequestMatcher implements RequestMatcher {
11     private Pattern allowedMethods = Pattern
12             .compile("^(GET|HEAD|TRACE|OPTIONS)$");
13
14     public boolean matches(HttpServletRequest request) {
15
16         if (execludeUrls != null && execludeUrls.size() > 0) {
17             String servletPath = request.getServletPath();
18             for (String url : execludeUrls) {
19                 if (servletPath.contains(url)) {
20                     return false;
21                 }
22             }
23         }
24         return !allowedMethods.matcher(request.getMethod()).matches();
25     }
26
27     /**
28      * 需要排除的url列表
29      */
30     private List<String> execludeUrls;
31
32     public List<String> getExecludeUrls() {
33         return execludeUrls;
34     }
35
36     public void setExecludeUrls(List<String> execludeUrls) {
37         this.execludeUrls = execludeUrls;
38     }
39 }
复制代码
这里添加了一个属性execludeUrls,允许人为排除哪些url。

然后在配置文件里,这样修改:

复制代码
1     <http entry-point-ref="loginEntryPoint" use-expressions="true">
2         ...
3         <intercept-url pattern="/rest/**" access="permitAll" />
4         ...
5         <csrf request-matcher-ref="csrfSecurityRequestMatcher"/>       
6     </http>
7    
8     <beans:bean id="csrfSecurityRequestMatcher" class="com.cnblogs.yjmyzz.utils.CsrfSecurityRequestMatcher">
9         <beans:property name="execludeUrls">
10             <beans:list>
11                 <beans:value>/rest/</beans:value>
12             </beans:list>
13         </beans:property>
14     </beans:bean>
复制代码
这里约定所有/rest/开头的都是Rest服务地址,上面的配置就把/rest/排除在csrf验证的范围之外了.

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [收藏 spring security] 推荐:

(收藏)Spring Security笔记:解决CsrfFilter与Rest服务Post方式的矛盾

- - jackyrong
基于Spring Security+Spring MVC的web应用,为了防止跨站提交攻击,通常会配置csrf,即:. 如果应用中有Post方式访问的Rest服务(参考下面的代码),会很不幸的发现,所有POST方式请求的服务会调用失败. 原因在于:启用csrf后,所有http请求都被会CsrfFilter拦截,而CsrfFilter中有一个私有类DefaultRequiresCsrfMatcher.

cxf + spring 的WS Security示例

- - RSS - IT博客云
WSPasswordCallback的 passwordType属性和 password属性都为null,你只能获得用户名(identifier),一般这里的逻辑是使用这个用户名到数据库中查询其密码,然后再设置到 password属性,WSS4J会自动比较客户端传来的值和你设置的这个值. 你可能会问为什么这里CXF不把客户端提交的密码传入让我们在 ServerPasswordCallbackHandler中比较呢.

Spring Security 实战干货:图解Spring Security中的Servlet过滤器体系

- - SegmentFault 最新的文章
我在 Spring Security 实战干货:内置 Filter 全解析对 Spring Security的内置过滤器进行了罗列,但是 Spring Security真正的过滤器体系才是我们了解它是如何进行"认证"、“授权”、“防止利用漏洞”的关键. Servlet Filter体系. 这里我们以 Servlet Web为讨论目标, Reactive Web暂不讨论.

Spring Boot 使用Spring security 集成CAS - CSDN博客

- -
      创建Maven工程:springboot-security-cas.       创建工程后,打开pom.xml,在pom.xml中加入以下内容:.           .           . 3.创建application.properties.

奔的家园 | CAS 与 Spring Security 3.1整合配置详解

- - Delicious/searchfull
该方式通过获取CAS系统里的角色,来支持CAS与Spring Security的关联,注意该文章authorities部分. 一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分. 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.

spring security 3.1.0 控制用户重复登陆

- - CSDN博客架构设计推荐文章
通过配置我们可以实现两个需求 1、限制不允许第二个用户登录,2、第二个登陆用户踢掉前一个登陆用户 . 假设你的spring架构已经可以使用了(其他的主要功能完成),需要增加登录限制功能. 注:这里只写配置不写原理(不懂的就问度娘),其实个人认为先配置好跑起来再研究下原理最好了. 通过sessionRegistry可以获取系统当前在线人数和登录用户信息.

spring security 3中推荐使用BCrypt算法加密密码

- - jackyrong
spring security 3中推荐使用BCrypt算法加密密码了,以前使用的是md5,. Md5PasswordEncoder 和 ShaPasswordEncoder,现在不推荐了,推荐用bcrpt. Bcrpt中的salt可以是随机的,比如:.   其中strenth为长度. 已有 0 人发表留言,猛击->> 这里<<-参与讨论.

Spring security oauth2最简单入门环境搭建--二、干货

- - ITeye博客
关于OAuth2的一些简介,见我的上篇blog: http://wwwcomy.iteye.com/blog/2229889 PS:貌似内容太水直接被鹳狸猿干沉. 友情提示 学习曲线:spring+spring mvc+spring security+Oauth2基本姿势,如果前面都没看过请及时关闭本网页.

Spring Security判断用户是否已经登录 - 简书

- -
方法一、JSP中检查user principal. 需要:.

盘点 Spring Security 框架中的八大经典设计模式

- - SegmentFault 最新的文章
上次有小伙伴建议,源码分析太枯燥了,要是能够结合设计模式一起来,这样更有助于大家理解 Spring Security 源码,同时还能复习一波设计模式. 因此松哥今天就试着整一篇,和大家来聊一聊 Spring Security 中涉及到的设计模式,不过 Spring Security 中涉及到的设计模式还是非常多的,松哥这里讲几个,剩下的欢迎小伙伴们留言补充.