Angular 9 没有在请求中设置 X-XSRF-TOKEN header
Angular 9 not setting X-XSRF-TOKEN header in the request
我必须保护我的 Web 应用程序免受 CSRF 的侵害,CSRF 是一个在客户端具有 Angular 9 的 .Net 核心 MVC Web 应用程序。
这是我试过的
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
services.AddMvc(option => option.EnableEndpointRouting = false);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
{
app.Use((context, next) =>
{
// CSRF cookie token generation
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
// The request token can be sent as a JavaScript-readable cookie,
// and Angular uses it by default.
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
// CSRF cookie token generation - end
return next.Invoke();
});
}
正在生成 XSRF-TOKEN cookie,但 Angular 未在请求中设置 X-XSRF-TOKEN header。
我没有对 Angular 请求部分进行任何代码更改。
Controller.cs
[ValidateAntiForgeryToken]
[HttpPost]
public IActionResult ProduceMessage([FromBody] OncRequestData oncRequestData)
{
OncRequestData _OncRequestData = new OncRequestData();
}
在 Angular 应用程序中,我添加了一个 httpintercepter 来提取和发送请求中的令牌 header
export class TokenInterceptorService implements HttpInterceptor {
token: string;
constructor(private xsrfTokenExtractor: HttpXsrfTokenExtractor) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if(req.method == "POST")
{
let xsrfToken = this.xsrfTokenExtractor.getToken();
const authReq = req.clone({ headers: req.headers.set("X-XSRF-TOKEN", xsrfToken) });
return next.handle(authReq);
}else{
return next.handle(req);
}
}
现在我从服务器收到错误请求错误 (400)
我通过以下更改暂时解决了这个问题。
- 我从操作方法中删除了 [ValidateAntiForgeryToken] 属性
- 添加了自定义中间件来验证所有 POST 请求
- 触发 ValidateRequestAsync(httpContext);验证请求的方法。
public class AntiforgeryValidationMiddleware
{
private readonly RequestDelegate _next;
public AntiforgeryValidationMiddleware(RequestDelegate next)
{
_next = next;
}
/// <summary>
/// Validate incoming request for CSRF token
/// </summary>
/// <param name="httpContext"></param>
/// <param name="antiforgery"></param>
/// <returns></returns>
public async Task InvokeAsync(HttpContext httpContext, IAntiforgery antiforgery)
{
try
{
// if the POST request is not from AD2BC call back
if (httpContext.Request.Method == "POST" && !httpContext.Request.Path.Equals("/Home/Auth"))
{
await antiforgery.ValidateRequestAsync(httpContext);
}
await _next(httpContext);
}
catch (AntiforgeryValidationException exception)
{
Log.Error("CSRF token validation failed" + exception.Message);
}
}
}
如果谁有更好的解决方案请告诉我
我必须保护我的 Web 应用程序免受 CSRF 的侵害,CSRF 是一个在客户端具有 Angular 9 的 .Net 核心 MVC Web 应用程序。
这是我试过的
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
services.AddMvc(option => option.EnableEndpointRouting = false);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
{
app.Use((context, next) =>
{
// CSRF cookie token generation
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
// The request token can be sent as a JavaScript-readable cookie,
// and Angular uses it by default.
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
// CSRF cookie token generation - end
return next.Invoke();
});
}
正在生成 XSRF-TOKEN cookie,但 Angular 未在请求中设置 X-XSRF-TOKEN header。
Controller.cs
[ValidateAntiForgeryToken]
[HttpPost]
public IActionResult ProduceMessage([FromBody] OncRequestData oncRequestData)
{
OncRequestData _OncRequestData = new OncRequestData();
}
在 Angular 应用程序中,我添加了一个 httpintercepter 来提取和发送请求中的令牌 header
export class TokenInterceptorService implements HttpInterceptor {
token: string;
constructor(private xsrfTokenExtractor: HttpXsrfTokenExtractor) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if(req.method == "POST")
{
let xsrfToken = this.xsrfTokenExtractor.getToken();
const authReq = req.clone({ headers: req.headers.set("X-XSRF-TOKEN", xsrfToken) });
return next.handle(authReq);
}else{
return next.handle(req);
}
}
现在我从服务器收到错误请求错误 (400)
我通过以下更改暂时解决了这个问题。
- 我从操作方法中删除了 [ValidateAntiForgeryToken] 属性
- 添加了自定义中间件来验证所有 POST 请求
- 触发 ValidateRequestAsync(httpContext);验证请求的方法。
public class AntiforgeryValidationMiddleware
{
private readonly RequestDelegate _next;
public AntiforgeryValidationMiddleware(RequestDelegate next)
{
_next = next;
}
/// <summary>
/// Validate incoming request for CSRF token
/// </summary>
/// <param name="httpContext"></param>
/// <param name="antiforgery"></param>
/// <returns></returns>
public async Task InvokeAsync(HttpContext httpContext, IAntiforgery antiforgery)
{
try
{
// if the POST request is not from AD2BC call back
if (httpContext.Request.Method == "POST" && !httpContext.Request.Path.Equals("/Home/Auth"))
{
await antiforgery.ValidateRequestAsync(httpContext);
}
await _next(httpContext);
}
catch (AntiforgeryValidationException exception)
{
Log.Error("CSRF token validation failed" + exception.Message);
}
}
}
如果谁有更好的解决方案请告诉我