2

我在 Angular 2 中有单独的前端项目而不使用 MVC,后端项目是 Web Api (Asp.Net Core),它们都托管在不同的域上。我实现了 AntiForgery 令牌功能,但它不起作用。

前端项目(UI)-http://localhost:8080/

后端项目(Web Api) -http://localhost:4823/

我能够XSRF-Token在每个请求中接收和发送 cookie,但 api 会400 Bad Request出错。我跟着这个链接 -Angular2 ASP.NET Core AntiForgeryToken

Startup.cs-

public void ConfigureServices(IServiceCollection services)
{
    services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
    services.AddCors(options =>
    {
        options.AddPolicy("AllowAllCorsPolicy",
        builder => builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader()
                   .AllowCredentials());
     });
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider, IAntiforgery antiforgery)
{
    app.Use(async (context, next) =>
      {
        if (context.Request.Path == "/")
           {
             //send the request token as a JavaScript-readable cookie, and Angular will use it by default
             var tokens = antiforgery.GetAndStoreTokens(context);
             context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions { HttpOnly = false });
           }
       }
}

控制器代码-

[EnableCors("AllowAllCorsPolicy")]
[ValidateAntiForgeryToken]
[Produces("application/json")]
[Route("api/Aoi")]
public class AoiController : Controller
{
 ...
}

角码——

let options = new RequestOptions({ headers: headers, withCredentials:true });
this._http.post(this.aoiUrl, bodydata, options)
       .map((res: Response) => {
          let data = res.json();
          return data;
})

在此处输入图像描述

4

4 回答 4

0

cookie 不能跨域共享。因此,即使您的 Web api 项目将 附加XSRF-TOKEN到其上下文响应中,它也不适用于托管在单独域中的前端应用程序。通过配置服务选项,我看到了一些在两个应用程序中使用固定cookie 名称AddAntiforgery()的解决方法。

于 2017-06-30T13:15:06.013 回答
0

我认为您应该能够通过启用 CORS 来完成这项工作。有关详细信息,请参阅此处 - https://docs.microsoft.com/en-us/aspnet/core/security/cors

于 2017-07-07T01:58:18.950 回答
0

我最近也一直在看这个,并做了一些测试,也找到了解决方法。解决方法还不错,它允许您开始开发更接近于使用端口的部署场景。

我发现在 .Net Core Web Api 应用程序中设置和启用 CORS 将不允许您使用内置的 AntiForgeryToken 机制。我找到的解决方案是使用 Nginx。

只需下载 Nginx 并将可执行文件和包放在您选择的位置。我使用 C:\nginx。

在您的位置,您将需要编辑 Nginx 配置文件。(./conf/nginx.conf)

在 nginx.conf 文件中,看到您的 server{} 部分类似于以下内容:

server {
  listen: 80;
  listen: 443 ssl;
  server_name: localhost;

  #My UI Project
        location ^~ / {
            proxy_pass http://127.0.0.1:4200/;
            proxy_set_header Upgrade $http_upgrade;
            #proxy_set_header Connection 'upgrade';
            proxy_set_header Connection $http_connection;
            proxy_set_header Host $host;
            proxy_http_version 1.1;
            proxy_cache_bypass $http_upgrade;
        }

        location ^~ /sockjs-node/ {
            proxy_pass htts://127.0.0.1:4200;
            proxy_set_header Upgrade $http_upgrade;
            #proxy_set_header Connection 'upgrade';
            proxy_set_header Connection $http_connection;
            proxy_set_header Host $host;
            proxy_http_version 1.1;
            proxy_cache_bypass $http_upgrade;
        }

        #My API Project
        location ^~ /myapi/ {
            proxy_pass http://127.0.0.1:5000;
            proxy_set_header Upgrade $http_upgrade;
            #proxy_set_header Connection 'upgrade';
            proxy_set_header Connection $http_connection;
            proxy_set_header Host $host;
            proxy_http_version 1.1;
            proxy_cache_bypass $http_upgrade;
        }
}

在这里,我列出了我在 Web 服务器 (ei:) 的根目录运行的 Angular UI 项目(“我的 UI” http://localhost

然后,我们使用与 Angular 项目相同的 url 列出 sockjs-node。

最后,我列出了我的 API 项目(“My Api”),并在该位置添加了/myapi/路径。然后我的 api 项目http://localhost/myapi可以从http://locahost. 现在两者都使用相同的域。

在开始开发工作时启动 nginx 服务器,然后像往常一样启动 api 项目和 Angular 项目。

全部运行后,您可以在 localhost 导航到您的应用程序,如果您想导航到 Api 项目中的端点,您可以转到类似http://localhost/myapi/api/values/1.

另请注意,我已在 nginx.conf 位置中注释掉了该行: proxy_set_header Connection 'upgrade';,而是使用了: proxy_set_header Connection $http_connection;。您将需要它才能将数据发送到非 GET 端点并正常工作。

另一件要认识到的事情,根据我在此设置中的发现,在使用 AntiforgeryToken 时,如果在您的 startup.cs 中设置这些, options.Filters.Add<AutoValidateAntiforgeryTokenAttribute>(); 或者 services.AddScoped<AutoValidateAntiforgeryTokenAttribute>(); 使用[AutoValidateAntiforgeryToken]类级别属性似乎不会启动任何验证。我必须将该[ValidateAntiForgeryToken]属性添加到我们要运行 Antiforgery 验证的方法中。也许有人可以评论那部分。

于 2019-05-10T19:00:00.843 回答
-1

像这样配置 Antiforgery cookie:

service.AddAntiforgery(options =>
            {
                options.HeaderName = "X-XSRF-TOKEN";
                options.Cookie.Name = "XSRF-TOKEN";
                options.Cookie.HttpOnly = false;
                options.Cookie.Path = "/";
                options.Cookie.SameSite = SameSiteMode.None;
            });
于 2018-03-24T19:29:36.920 回答