我在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;
})
答案 0 :(得分:0)
Cookie不能跨跨域共享。因此,即使您的web api项目将XSRF-TOKEN
附加到其上下文响应,但是在单独的域中托管的前端应用程序可以使用 。通过配置AddAntiforgery()
服务的选项,我看到了在两个应用程序中使用固定 cookie名称的一些变通方法。
答案 1 :(得分:0)
我认为你应该能够通过启用CORS来实现这一目标。有关详细信息,请参阅此处 - https://docs.microsoft.com/en-us/aspnet/core/security/cors
答案 2 :(得分:0)
配置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 :(得分:0)
我最近也一直在研究此问题,并进行了一些测试,还找到了解决方法。解决方法还不错,通过使用端口,您可以使开发工作更接近于部署方案。
我发现在.Net Core Web Api应用程序中设置并启用CORS不允许您使用内置的AntiForgeryToken机制。我发现的解决方案是使用Nginx。
只需下载Nginx,然后将可执行文件和软件包放在您选择的位置。我使用C:\ nginx。
在您的位置,您将需要编辑Nginx配置文件。 (./conf/nginx.conf)
在nginx.conf文件中,您的服务器{}部分看起来与此类似:
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服务器(例如:http://localhost
)的根目录下运行的Angular UI项目(“我的UI”)
然后我们使用与Angular项目相同的网址列出sockjs-node。
最后,我列出了我的API项目(“我的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进行设置时,根据我在此设置中发现的另一件事,需要进行设置,如果在启动文件中设置了这些文件...
options.Filters.Add<AutoValidateAntiforgeryTokenAttribute>();
要么
services.AddScoped<AutoValidateAntiforgeryTokenAttribute>();
并且还使用[AutoValidateAntiforgeryToken]
类级别属性似乎并未启动任何验证。我必须将[ValidateAntiForgeryToken]
属性添加到我们要运行防伪验证的方法中。也许有人可以对此发表评论。