angularjs - 如何实现跨域请求的csrf保护

标签 angularjs cookies cross-domain csrf csrf-protection

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

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

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

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

我还尝试在浏览器中的 Web UI 本身上实现 csrf cookie 的创建,但浏览器不会将 cookie 发送到 Web 服务,因为它位于不同的域中。

那么,我的问题是,对于这种情况如何实现csrf保护?

最佳答案

您的做法是正确的:

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 请求 header 中提供。来自其他域的伪造 GET 请求(由 HTML 标记触发,如 <img src=""> )无法设置自定义 header ,因此您可以通过以下方式断言该请求来自您域上的 javascript 客户端。

以下是如何实现您正在研究的想法,假设您有 api.domain.comui.domain.com :

1) 用户从 ui.domain.com 加载 Angular 客户端

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

2) 使用 HttpOnly 进行回复身份验证 cookie,名为 authCookie ,以及自定义 header ,例如X-Auth-Cookie ,其中此 header 的值是链接到由 authCookie 标识的 session 的唯一值。

3) Angular 客户端读取 X-Auth-Cookie header 值并将该值存储在 XSRF-TOKEN 中其域上的 cookie,ui.domain.com

  • 现在你有:

    • XSRF-TOKEN cookie ui.domain.com
    • authCookie cookie api.domain.com

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

5) 您的服务器断言 X-XSRF-TOKEN 的值链接到由 authCookie 的值标识的同一 session

我希望这有帮助!我还写过有关 Angular token 身份验证的文章,Token Based Authentication for Single Page Apps (SPAs) (免责声明:我在 Stormpath 工作)

关于angularjs - 如何实现跨域请求的csrf保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27793424/

相关文章:

javascript - 为什么我的对象没有在 Angular View 中更新?

http - 当一段时间过去或浏览器关闭时,cookie 会过期吗?

c# - Asp.Net Core 3.1 Cookie 身份验证循环到登录页面

javascript - 跨(子)域 AJAX POST 请求(带文件/大体)

browser - 跨子域/端口 socket.io - 如何处理?

javascript - 用于 chrome 扩展的 iFrame 的跨域问题

node.js - Angularjs 应用程序托管在 J2EE 服务器上而不是 Node.js 服务器上

javascript - ng-init 在选择选项中覆盖 ng-model (添加了 plunker)

ios - Alamofire 会自动存储 cookie 吗?

javascript - 如何创建从一个 ng-view 到另一个 ng-view 的缩放动画?