如何为跨域请求实施CSRF保护 [英] how to implement csrf protection for cross domain requests
问题描述
我有两个Web应用程序,一个用于AngularJS中的Web UI,另一个用于Java中的REST Web服务.两者都部署在单独的域中.
I have two web apps, one for the Web UI in AngularJS and one for the REST webservices in Java. Both are deployed on separate domains.
应用程序使用cookie进行身份验证.每当用户输入有效的用户名和密码时,服务器都会返回仅http的cookie,其中包含该令牌,并且该cookie会在所有请求中传递.我在两个应用程序上都启用了CORS,这就是会话cookie正常运行的原因.
The applications uses cookie for authentication. Whenever user enters a valid username and password, server returns a http only cookie back containing the token and that cookie is passed across all requests. I have enabled CORS on both apps, thats why the session cookie is working properly.
现在,我正在尝试为此添加CSRF保护.我试图使用csrf cookie,在该服务器中,服务器将在其中发送csrf cookie(不是httponly)作为REST响应的一部分,并且UI将从cookie中读取该值,并将该值传递给其他REST调用的csrf令牌标头中.
Now, I am trying to add CSRF protection for this. I was trying to use the csrf cookie where in the server will send the csrf cookie(not httponly) as part of REST response and the UI will read the value from the cookie and pass that in a csrf token header for the other REST calls.
我所面对的这种方法的问题在于,由于服务器位于不同的域中,因此我无法在AngularJs中使用$ cookies读取cookie.有没有办法读取该Cookie的值? 如果没有,那么我可以通过其他方式实现CSRF吗?
The problem with this approach I am facing is that since the server is in different domain, I cannot read the cookie using $cookies in AngularJs. Is there a way to read a value of that cookie? If not, then can I implement CSRF in some other way?
我还尝试在浏览器的Web UI本身上实现csrf cookie的创建,但是浏览器不会将cookie作为不同域的webservice发送到webservice.
I also tried to implement the creation of the csrf cookie on the Web UI itself in the browser but the browser does not send the cookie to the webservice as its in different domain.
所以,我的问题是如何针对这种情况实施csrf保护?
So, my question is how to implement csrf protection for this kind of situation?
推荐答案
您在正确的轨道上与此:
You were on the right track with this:
我还尝试在浏览器的Web UI本身上实现csrf cookie的创建,但是浏览器不会将cookie作为不同域中的webservice发送到webservice.
I also tried to implement the creation of the csrf cookie on the Web UI itself in the browser but the browser does not send the cookie to the webservice as its in different domain.
CSRF cookie并不是要发送"到服务器,而是要由客户端读取,然后在自定义HTTP请求标头中提供.来自其他域的伪造的GET请求(由<img src="">
之类的HTML标记触发)无法设置自定义标头,因此您可以通过这种方式断言该请求来自您域中的javascript客户端.
The CSRF cookie isn't meant to be "sent" to the server, it is meant to be read by the client and then supplied in a custom HTTP request header. Forged GET requests (triggered by HTML tags such as <img src="">
) from other domains cannot set custom headers, so this is how you assert that the request is coming from a javascript client on your domain.
在这里,您可以执行您正在研究的想法,假设您拥有api.domain.com
和ui.domain.com
:
Here is how you can implement the idea you were working on, imagine you have api.domain.com
and ui.domain.com
:
1)用户从ui.domain.com
2)用户将来自Angular客户端的身份验证信息发布到api.domain.com
2) User posts authentication information from Angular client to api.domain.com
2)服务器使用称为authCookie
的HttpOnly
身份验证cookie和自定义标头(例如, X-Auth-Cookie
,其中此标头的值是一个唯一值,该值链接到由authCookie
2) Sever replies with an HttpOnly
authentication cookie, called authCookie
, and a custom header e.g. X-Auth-Cookie
, where the value of this header is a unique value that is linked to the session that is identified by the authCookie
3)Angular客户端读取X-Auth-Cookie
标头值并将该值存储在其域ui.domain.com
3) The Angular client reads the X-Auth-Cookie
header value and stores that value in a XSRF-TOKEN
cookie on its domain, ui.domain.com
-
现在您有了:
So now you have:
-
XSRF-TOKEN
cookieapi.domain.com
上的 -
authCookie
cookie
ui.domain.com
上的XSRF-TOKEN
cookie onui.domain.com
authCookie
cookie onapi.domain.com
4)用户在api.domain.com
上请求受保护资源.浏览器将自动提供authCookie
值,而Angular将自动发送X-XSRF-TOKEN
标头,并将发送从XSRF-TOKEN
cookie中读取的值
4) User makes a request of a protected resource on api.domain.com
. The browser will automatically supply the authCookie
value, and Angular will automatically send the X-XSRF-TOKEN
header, and will send the value that it reads from the XSRF-TOKEN
cookie
5)您的服务器断言X-XSRF-TOKEN
的值已链接到由authCookie
5) Your server asserts that the value of X-XSRF-TOKEN
is linked to the same session that is identified by the value of the authCookie
我希望这会有所帮助!我还写过有关Angular令牌认证的信息,基于单页应用(SPA)的基于令牌的认证(免责声明:我在 Stormpath 工作)
I hope this helps! I've also written about token authentication for Angular, Token Based Authentication for Single Page Apps (SPAs) (Disclaimer: I work at at Stormpath)
这篇关于如何为跨域请求实施CSRF保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!