`

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

 
阅读更多
基于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验证的范围之外了.
分享到:
评论

相关推荐

    vue+spring boot整合笔记和代码资料

    3. **前后端通信**:Vue.js使用axios或fetch等库进行Ajax请求,与Spring Boot提供的REST API进行交互。发送GET、POST、PUT、DELETE请求,获取或修改后端数据。 4. **安全认证**:在整合过程中,安全性是必须考虑的...

    springmvc课堂笔记(两天)

    9. **SpringMVC与其他Spring模块的集成**:例如与Spring Security、Spring Data JPA等的协同工作。 10. **最佳实践和案例分析**:分享实际项目中的经验和技巧,以及常见问题的解决方案。 这些知识点的掌握,将使你...

    webservice学习笔记

    Spring框架的Spring Boot和Spring MVC为开发RESTful API提供了强大支持,而Jersey和Dropwizard等库则提供了REST服务的快速构建工具。 总的来说,Web服务是实现跨平台、跨系统通信的重要手段,理解其工作原理和技术...

    NotesApiSpring:JavaSpring中NotesApp的API

    在Java Spring框架中,开发一个NotesApp的API是一项常见的任务,它涉及到Web服务的构建,以便客户端能够创建、读取、更新和删除(CRUD)笔记。`NotesApiSpring`项目是一个实例,展示了如何利用Spring Boot和相关技术...

    delivery-algaworks:curso imersivo EspecialistaSpringREST(ESR)

    《深度学习Spring REST(ESR)课程》是Algaworks提供的一个专业级Java课程,旨在帮助开发者精通Spring框架,特别是其在构建RESTful Web服务方面的应用。本课程以Java编程语言为基础,深入探讨了如何利用Spring框架的...

    基于java的美食网站的设计与实现.zip

    8. **RESTful API设计**:为了与其他服务或移动应用交互,项目可能采用了REST(Representational State Transfer)架构风格设计API,使用HTTP协议的GET、POST、PUT和DELETE等方法进行资源操作。 9. **测试与部署**...

    course-springboot-2-java-

    描述中的信息虽然较为空泛,但我们可以从中推断出这个压缩包可能包含一系列与学习Spring Boot 2相关的Java项目、源代码、笔记或其他教学材料。"course-springboot-2-java--master"可能是项目仓库的主分支名,通常在...

    thin-wiki:也许您需要的并不是什么笔记本,而真正需要的是一个属于自己的Wiki

    Spring Boot的@RestController注解可以帮助我们快速创建REST服务。用户可以通过POST请求创建新页面,PUT请求更新页面,GET请求获取页面内容,DELETE请求删除页面。 安全方面,Spring Security可以用来处理用户认证...

Global site tag (gtag.js) - Google Analytics