使用Aps.Net Core在Angular 2和Web Api中实现防伪令牌 [英] AntiForgery Token implementation in Angular 2 and Web Api using Aps.Net Core

查看:113
本文介绍了使用Aps.Net Core在Angular 2和Web Api中实现防伪令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在不使用MVC的情况下在Angular 2中有一个单独的前端项目,而后端项目是Web Api(Asp.Net Core),它们都托管在不同的域中.我实现了AntiForgery令牌功能,但无法正常工作.

I have separate frontend project in Angular 2 without using MVC and backend project is Web Api (Asp.Net Core) both are hosted on different domain. I implemented AntiForgery token functionality but it is not working.

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

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

Backend project (Web Api) - http://localhost:4823/

我能够在每个请求中接收和发送XSRF-Token cookie,但是api给出了400 Bad Request错误. 我点击了此链接- Angular2 ASP.NET Core AntiForgeryToken

I am able to receive and send XSRF-Token cookie in every request but api gives 400 Bad Request error. I followed this link- 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;
})

推荐答案

我最近也一直在研究此问题,并进行了一些测试,还找到了解决方法.解决方法还不错,通过使用端口,您可以使开发工作更接近于部署方案.

I too have been looking at this lately and have done some testing and have also found a work around. The work around isn't too bad and allows you to start your development closer to a deployment scenario over working with ports.

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

I have found that setting up and enabling CORS in a .Net Core Web Api app will not allow you to use the built-in AntiForgeryToken mechanism. The solution that I found was to use Nginx.

只需下载Nginx,然后将可执行文件和程序包放置在您选择的位置.我使用C:\ nginx.

Simply download Nginx and place the executable and package in a location of your choice. I use C:\nginx.

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

In your location, you will need to edit the Nginx config file. (./conf/nginx.conf)

在nginx.conf文件中,您的服务器{}部分看起来与此类似:

In the nginx.conf file, see that your server{} part looks similar to this:

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:http://localhost)的根目录上运行的Angular UI项目(我的UI")

Here I list my Angular UI project ("My UI") that I have running at the root of the web server (ei: http://localhost)

然后我们使用与Angular项目相同的网址列出sockjs-node.

We then to list out the sockjs-node using the same url as our Angular project.

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

Last, I list my API project ("My Api") and in the location, I have added the /myapi/ path. My api project will then be accessible from http://localhost/myapi and my Angular project accessible from http://locahost. Now both are using the same domain.

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

Start up the nginx server when you are starting your development work and then start your api project and your Angular project as you normally would.

全部运行之后,您可以导航至本地主机上的应用程序,如果要导航至Api项目中的终结点,则可以使用http://localhost/myapi/api/values/1之类的东西.

After all are running, you can navigate to your app at localhost and if you want to navigate to an endpoint in your Api project, you would go to something like http://localhost/myapi/api/values/1.

还要注意,我已经注释掉了这一行: 在nginx.conf位置中使用proxy_set_header Connection 'upgrade';并代替使用: proxy_set_header Connection $http_connection;.您需要这样做,以便将数据发送到非GET端点并正常工作.

Also notice that I have commented out the line: proxy_set_header Connection 'upgrade'; in the nginx.conf locations and instead used: proxy_set_header Connection $http_connection;. You will need this in order to have data sent and working properly to non-GET endpoints.

使用此设置我发现的另一件事是,在使用AntiforgeryToken时,在您的startup.cs中设置其中的一个... options.Filters.Add<AutoValidateAntiforgeryTokenAttribute>(); 或者 services.AddScoped<AutoValidateAntiforgeryTokenAttribute>(); 并且还使用[AutoValidateAntiforgeryToken]类级别属性似乎并未启动任何验证.我必须在要运行Antiforgery验证的方法中添加[ValidateAntiForgeryToken]属性.也许有人可以对此发表评论.

Another thing to be cognizant of, from what I have found with this setup, when using the AntiforgeryToken, setting either if these in your startup.cs... options.Filters.Add<AutoValidateAntiforgeryTokenAttribute>(); or services.AddScoped<AutoValidateAntiforgeryTokenAttribute>(); and also using the [AutoValidateAntiforgeryToken] class level attribute does NOT seem to kick off any validation. I have to add the [ValidateAntiForgeryToken] attribute to methods where we want to run the Antiforgery validation. Perhaps someone can comment on that part.

这篇关于使用Aps.Net Core在Angular 2和Web Api中实现防伪令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆