我有两个网络应用程序,一个用于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保护?
答案 0 :(得分:14)
你走在正确的轨道上:
我还尝试在浏览器中在Web UI上实现csrf cookie的创建,但是浏览器不会将cookie作为其在不同域中的web服务发送。
CSRF Cookie并非意图发送&#34;对于服务器,它意味着由客户端读取,然后在自定义HTTP请求头中提供。来自其他域的伪造GET请求(由<img src="">
等HTML标记触发)无法设置自定义标头,因此您可以断言该请求来自您域中的javascript客户端。
以下是如何实施您正在处理的想法,假设您有api.domain.com
和ui.domain.com
:
1)用户从ui.domain.com
2)用户将Angular客户端的身份验证信息发布到api.domain.com
2)Sever使用名为HttpOnly
的{{1}}身份验证Cookie和自定义标头回复,例如authCookie
,此标头的值是一个唯一值,该值链接到X-Auth-Cookie
3)Angular客户端读取authCookie
标头值并将该值存储在其域X-Auth-Cookie
XSRF-TOKEN
cookie中
现在你有了:
ui.domain.com
Cookie XSRF-TOKEN
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