【问题标题】:AntiForgery Token implementation in Angular 2 and Web Api using Aps.Net Core使用 Aps.Net Core 在 Angular 2 和 Web Api 中实现 AntiForgery 令牌
【发布时间】:2017-12-04 03:01:47
【问题描述】:

我在 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
{
 ...
}

Angular 代码-

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

【问题讨论】:

    标签: angular asp.net-web-api asp.net-core antiforgerytoken x-xsrf-token


    【解决方案1】:

    我最近也一直在研究这个问题,并进行了一些测试,也找到了解决方法。解决方法还不错,让您可以在更接近部署场景的情况下开始开发,而不是使用端口。

    我发现在 .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 服务器根目录运行的 Angular UI 项目(“我的 UI”)(ei:http://localhost

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

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      像这样配置 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;
                  });
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-23
            • 2016-04-29
            • 2017-05-20
            • 2014-07-21
            • 2021-02-28
            • 1970-01-01
            相关资源
            最近更新 更多