如何为跨域请求实现csrf保护

时间:2015-01-06 06:41:23

标签: angularjs cookies cross-domain csrf csrf-protection

我有两个网络应用程序,一个用于AngularJS中的Web UI,另一个用于Java中的REST Web服务。两者都部署在不同的域中。

应用程序使用cookie进行身份验证。每当用户输入有效的用户名和密码时,服务器返回包含令牌的仅http cookie,并且cookie将在所有请求中传递。我在两个应用程序上启用了CORS,这就是会话cookie正常工作的原因。

现在,我正在尝试为此添加CSRF保护。我试图使用csrf cookie,在服务器中将发送csrf cookie(而不是httponly)作为REST响应的一部分,UI将从cookie读取值并将其传递到csrf令牌头中以用于其他REST调用。

我遇到的这种方法的问题是,由于服务器位于不同的域中,我无法使用AngularJs中的$ cookies读取cookie。有没有办法读取该cookie的值? 如果没有,那么我可以用其他方式实现CSRF吗?

我还尝试在浏览器中在Web UI上实现csrf cookie的创建,但是浏览器不会将cookie作为其在不同域中的web服务发送。

所以,我的问题是如何为这种情况实施csrf保护?

3 个答案:

答案 0 :(得分:14)

你走在正确的轨道上:

  

我还尝试在浏览器中在Web UI上实现csrf cookie的创建,但是浏览器不会将cookie作为其在不同域中的web服务发送。

CSRF Coo​​kie并非意图发送&#34;对于服务器,它意味着由客户端读取,然后在自定义HTTP请求头中提供。来自其他域的伪造GET请求(由<img src="">等HTML标记触发)无法设置自定义标头,因此您可以断言该请求来自您域中的javascript客户端。

以下是如何实施您正在处理的想法,假设您有api.domain.comui.domain.com

1)用户从ui.domain.com

加载Angular客户端

2)用户将Angular客户端的身份验证信息发布到api.domain.com

2)Sever使用名为HttpOnly的{​​{1}}身份验证Cookie和自定义标头回复,例如authCookie,此标头的值是一个唯一值,该值链接到X-Auth-Cookie

标识的会话

3)Angular客户端读取authCookie标头值并将该值存储在其域X-Auth-Cookie

XSRF-TOKEN cookie中
  • 现在你有了:

      {li} ui.domain.com Cookie XSRF-TOKEN {li} ui.domain.com Cookie authCookie

4)用户在api.domain.com上发出受保护资源的请求。浏览器将自动提供api.domain.com值,Angular会自动发送authCookie标头,并会发送从X-XSRF-TOKEN Cookie中读取的值

5)您的服务器断言XSRF-TOKEN的值链接到由X-XSRF-TOKEN

的值标识的同一会话

我希望这有帮助!我还写过关于Angular的令牌认证,Token Based Authentication for Single Page Apps (SPAs)(免责声明:我在Stormpath工作)

答案 1 :(得分:3)

Angularjs内置了对CSRF的支持,但不幸的是它不能跨域工作,所以你必须建立自己的。

我设法通过在第一个请求中首先在标头和Cookie中返回随机标记来使其正常工作。要阅读标题,您需要将其添加到Access-Control-Expose-Headers。然后将其添加到所有帖子

$http.get('url').
    success(function(data, status, headers) {
        $http.defaults.headers.post['X-XSRF-TOKEN'] = headers('XSRF-TOKEN');
    });

然后在服务器上,您可以将cookie值与标题中的值进行比较,以确保它们相同。

答案 2 :(得分:0)

$ http docs:Angular提供了一种机制来对抗XSRF。执行XHR请求时,但不会为跨域请求设置。

这是一个小的lib放在一起可能会帮助你https://github.com/pasupulaphani/angular-csrf-cross-domain