博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring REST 配置CSRF防护
阅读量:6258 次
发布时间:2019-06-22

本文共 3216 字,大约阅读时间需要 10 分钟。

hot3.png

Spring REST 配置CSRF防护

内容从以下几个方面展开

  • 什么是CSRF防护
  • 如何运用CSRF进行防御(WEB)
  • 如何将CSRF防御,运用到REST中 

1.什么是CSRF

CSRF 攻击简单来说,是多Tab页面浏览器的一个安全漏洞,比如你正在访问A网站,此时如果浏览器有你的cookie,并且session没有过期,此时你去访问B网站,那么B网站可以直接调用A网站的接口,而A网站则认为是你本人进行的操作。以下是图示:

2.如何进行防御

对CSRF进行防御,可以通过加Token.也就是当你访问A网站的时候,A会给你一个token,然后,接下去的post请求,你需要把token带上,不然服务器则拒绝接收这个请求。 

- 1. token的产生:spring-security 4.0之后默认开启csrf,可以直接产生csrf token。 
- 2. token的存储:这里存储是指服务端的存储,token是存储在session中。 
- 3. token的传送:token可以通过cookie,也可以放在header中自定义的属性中。 
- 4. token的接收和返回:前段收到http respon 之后,需要把相应的token返回回来。 
- 5. token校验:服务器端对自己持有的token和客户端反馈回来的token进行校验,决定是否拒绝服务(拒绝服务可以自定义)。

3.REST 的CSRF防御

一般写REST服务(也就是直接@ResponseBody)返回json字符串,则可以把token加在header里头的自定义属性中,为什么不能直接加在header中的cooike里,spring-sercurity官方给出的答案:

One might ask why the expected CsrfToken isn’t stored in a cookie by default. This is because there are known exploits in which headers (i.e. specify the cookies) can be set by another domain. This is the same reason Ruby on Rails no longer skips CSRF checks when the header X-Requested-With is present. See this webappsec.org thread for details on how to perform the exploit. Another disadvantage is that by removing the state (i.e. the timeout) you lose the ability to forcibly terminate the token if it is compromised.

翻译一下: 

- 1.cookie可以被其他域设置 
- 2.cookie是没有状态的,但是如果是session(含有过期时间),则可以使session过期,从而使token失效。(如有出入,欢迎拍砖)

既然如此,那么需要在header中加入token,我们只要注册一个Filter,就可以完成这个功能: 

- STEP 1 创建Filter

/** * * "将CSRF TOKEN加入到header中" * * Created by hzlaojiaqi on 2016/9/13. */public class CsrfTokenResponseHeaderBindingFilter extends OncePerRequestFilter {    protected static final String REQUEST_ATTRIBUTE_NAME = "_csrf";    protected static final String RESPONSE_HEADER_NAME = "X-CSRF-HEADER";    protected static final String RESPONSE_PARAM_NAME = "X-CSRF-PARAM";    protected static final String RESPONSE_TOKEN_NAME = "X-CSRF-TOKEN";    @Override    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, javax.servlet.FilterChain filterChain) throws ServletException, IOException {        CsrfToken token = (CsrfToken) request.getAttribute(REQUEST_ATTRIBUTE_NAME);        if (token != null) {            response.setHeader(RESPONSE_HEADER_NAME, token.getHeaderName());            response.setHeader(RESPONSE_PARAM_NAME, token.getParameterName());            response.setHeader(RESPONSE_TOKEN_NAME , token.getToken());        }        filterChain.doFilter(request, response);    }}

 

  • STEP 2 加入到过滤器中

    @Configuration@EnableWebSecuritypublic class SecurityConfigure extends WebSecurityConfigurerAdapter {private static final Logger THIRDPARTY_LOG = LoggerFactory.getLogger("THIRDPARTY_LOGGER");@AutowiredUserService userService;protected  void configure(HttpSecurity httpSecurity) throws Exception {    CsrfTokenResponseHeaderBindingFilter csrfTokenFilter = new CsrfTokenResponseHeaderBindingFilter();    CustomAccessDeniedHandler accessDeniedHandler=new CustomAccessDeniedHandler();    httpSecurity.addFilterAfter(csrfTokenFilter,CsrfFilter.class);}}

实验

    1. 首先进行Get请求,获取header中CSRF的token(图片忘记保存了)
    1. 在header中加入token,发起post请求
    1. 不在header中加入token,发起post请求

情况2 带header发起token

 

可以看到,服务器端正确返回数据。

情况3 不带header发起token

 

可以看到,服务器端 拒绝了我们的请求。

转载于:https://my.oschina.net/u/2552286/blog/1830535

你可能感兴趣的文章
[转载]如何破解Excel VBA密码
查看>>
【BZOJ】2563: 阿狸和桃子的游戏
查看>>
redis 中文字符显示
查看>>
国内外MD5在线解密网站
查看>>
【OC语法要闻速览】一、方法调用
查看>>
Git-命令行-删除本地和远程分支
查看>>
本文将介绍“数据计算”环节中常用的三种分布式计算组件——Hadoop、Storm以及Spark。...
查看>>
顺序图【6】--☆☆
查看>>
Docker Swarm 让你事半功倍
查看>>
[转]IC行业的牛人
查看>>
javaScript事件(四)event的公共成员(属性和方法)
查看>>
linux系统常用命令
查看>>
在 Word 中的受支持的区域设置标识符的列表
查看>>
Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明2
查看>>
An easy to use android color picker library
查看>>
Oracle SID爆破工具SidGuess
查看>>
批处理常用命令总结2
查看>>
解读ASP.NET 5 & MVC6系列(9):日志框架
查看>>
Android -- 自定义View小Demo,绘制钟表时间(一)
查看>>
信息检索Reading List
查看>>