【问题标题】:CSRF Token validation fails in ASP.NET Core with Angular使用 Angular 的 ASP.NET Core 中的 CSRF 令牌验证失败
【发布时间】:2020-12-31 13:39:46
【问题描述】:

我正在尝试使用 CSRF-Token 保护我的应用程序,因此我使用了 Angular 文档。他们声明,如果在 Cookies 中有一个名为 XSRF-TOKEN 的 cookie,那么这个 cookie 将自动在 Headers 中提供给后端,这确实是真的。每次我从我的 Angular 前端应用程序发出 POST 请求时,cookie 都会放在 Headers 中(作为 X-XSRF-TOKEN)。因此,我在 ASP .NET Core 中将默认的 Anti Forgery Token Cookie 名称更改为 XSRF-TOKEN:

// Startup.cs
services.AddAntiforgery(options =>
{
    options.HeaderName = "X-XSRF-TOKEN";
    options.Cookie = new CookieBuilder()
    {
        Name = "XSRF-TOKEN"
    };
});

我还在请求流中提供了令牌属性作为过滤器:

services.AddControllers(opt =>
{
    opt.Filters.Add(typeof(LoadFilter), Int32.MinValue); // my other custom filter
    opt.Filters.Add<AutoValidateAntiforgeryTokenAttribute>();
})

还有一个中间件负责将令牌存储在 cookie 中并在 POST 请求到来时对其进行验证:

    public class ValidateAntiForgeryTokenMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IAntiforgery _antiForgery;

        public ValidateAntiForgeryTokenMiddleware(RequestDelegate next, IAntiforgery antiForgery)
        {
            _next = next;
            _antiForgery = antiForgery;
        }

        public async Task Invoke(HttpContext context)
        {
            if (HttpMethods.IsGet(context.Request.Method))
            {
                _antiForgery.GetAndStoreTokens(context);
            }
                
            if (HttpMethods.IsPost(context.Request.Method))
            {
                await _antiForgery.ValidateRequestAsync(context);
            }
            await _next(context);
        }
    }

    public static class ApplicationBuilderExtensions
    {
        public static IApplicationBuilder UseAntiForgeryTokens(this IApplicationBuilder app)
        {
            return app.UseMiddleware<ValidateAntiForgeryTokenMiddleware>();
        }
    }

现在,每当我向后端服务器发出 GET 请求时,都会设置一个 XSRF-TOKEN cookie。 但是,当我使用具有相同值的 XSRF-TOKEN cookie 和 X-XSRF-TOKEN 标头发出 POST 请求时,会出现错误。 第一个错误,在我的本地开发机器上:

防伪令牌验证失败。验证提供的防伪令牌失败。交换了 cookie 令牌和请求令牌

第二个错误,在我的开发服务器上,产生另一个错误,即使代码相同:

所需的防伪cookie“.AspNetCore.Antiforgery.6zP9GDvCs-o”不存在。

另外,如果我在 ValidateAntiForgeryTokenMiddleware 中手动添加 cookie,一切似乎都正常工作。但是,我有两个 XSRF-TOKENS,这似乎不是一个好的解决方案,因为它将安全方面放在另外两个地方,而我认为一个 cookie 就足够了。

【问题讨论】:

    标签: asp.net angular cookies csrf


    【解决方案1】:

    在角边添加拦截器。确保在每个请求中添加 withCredentials: true。

    http-xsrf-interceptor.ts

    import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, 
    HttpXsrfTokenExtractor } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class XsrfInterceptor implements HttpInterceptor {
    constructor(private tokenExtractor: HttpXsrfTokenExtractor) { }
    
    intercept(req: HttpRequest<any>, next: HttpHandler): 
    Observable<HttpEvent<any>> {
        req = req.clone({ withCredentials: true });
        const headerName = 'X-XSRF-TOKEN';
        const token = this.tokenExtractor.getToken() as string;
        if (token !== null) {
            req = req.clone({ headers: req.headers.set(headerName, token) });
        }
        return next.handle(req);
      }
    }
    

    app.module.ts - 在提供者部分。

       {
            provide: HTTP_INTERCEPTORS,
            useClass: XsrfInterceptor,
            multi: true
        },
    

    【讨论】:

      猜你喜欢
      • 2014-11-12
      • 2016-09-09
      • 2012-05-16
      • 2014-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 2020-08-22
      相关资源
      最近更新 更多