繁体   English   中英

Angular2 ASP.NET Core AntiForgeryToken

[英]Angular2 ASP.NET Core AntiForgeryToken

我有一个Angular2应用程序。 它在ASP.NET 5(Core)中运行。
它使Http调用控制器工作正常。

但现在我需要建立Cross Site Scripting投影。

如何在每个Http请求上生成新令牌,然后在Angular2应用程序中执行AntiForgeryToken检查?

注意:我在Angular中的数据表单不是从MVC视图生成的,而是完全用Angular2编写并仅调用Web服务。

我见过的所有例子都已过时,不起作用/不起作用。

如何整合在Angular2 AntiForgeryToken检查针对ASP.NET 5,其中形式是纯粹的角?

谢谢。

不需要自定义操作筛选器。 它可以在Startup.cs中连接起来。

using Microsoft.AspNetCore.Antiforgery;

(...)

public void ConfigureServices(IServiceCollection services)
{
  services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

  (...)
}

public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
  app.Use(next => context =>
  {
    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 });
    }
    return next(context);
  });

  (...)
}

然后,您需要在控制器中的所有内容是[ValidateAntiForgeryToken]装饰器,无论您希望强制执行哪个令牌。

作为参考,我在这里找到了这个解决方案 - AspNet AntiForgery Github第29期

我正在使用动作过滤器来发送请求令牌。 只需将其应用于您想要新的防伪标记的操作,例如Angular2 SPA,WebAPI操作等。

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class AngularAntiForgeryTokenAttribute : ActionFilterAttribute
{
    private const string CookieName = "XSRF-TOKEN";
    private readonly IAntiforgery antiforgery;

    public AngularAntiForgeryTokenAttribute(IAntiforgery antiforgery)
    {
        this.antiforgery = antiforgery;
    }

    public override void OnResultExecuting(ResultExecutingContext context)
    {
        base.OnResultExecuting(context);

        if (!context.Cancel)
        {
            var tokens = antiforgery.GetAndStoreTokens(context.HttpContext);

            context.HttpContext.Response.Cookies.Append(
                CookieName,
                tokens.RequestToken,
                new CookieOptions { HttpOnly = false });
        }
    }
}
/* HomeController */

[ServiceFilter(typeof(AngularAntiForgeryTokenAttribute), IsReusable = true)]
public IActionResult Index()
{
    return View();
}

/* AccountController */

[HttpPost()]
[AllowAnonymous]
[ValidateAntiForgeryToken]
// Send new antiforgery token
[ServiceFilter(typeof(AngularAntiForgeryTokenAttribute), IsReusable = true)]
public async Task<IActionResult> Register([FromBody] RegisterViewModel model)
{
    //...
    return Json(new { }); 
}

在Startup中注册该属性,并配置Antiforgery服务以读取请求令牌表单“X-XSRF-TOKEN”标头。

public class Startup
{
    // ...

    public void ConfigureServices(IServiceCollection services)
    {
        // ...

        services.AddScoped<AngularAntiForgeryTokenAttribute>();
        services.AddAntiforgery(options =>
        {
            options.HeaderName = "X-XSRF-TOKEN";
        });
    }
}

我认为您需要制作自定义AntiForgeryValidationToken属性,该属性支持通过标头而不是表单值发送令牌。 然后将令牌添加到您的Angular2应用程序的每个请求的标头中。 此处的示例如何在Angular2中设置全局自定义标头?

要从标头验证令牌,您可以使用以下内容:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public sealed class ValidateHeaderAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException(nameof(filterContext));
            }

            var httpContext = filterContext.HttpContext;
            if (httpContext.Request.Headers["__RequestVerificationToken"] == null)
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                httpContext.Response.StatusDescription = "RequestVerificationToken missing.";

                filterContext.Result = new JsonResult
                {
                    Data = new { ErrorMessage = httpContext.Response.StatusDescription },
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet
                };
                return;
            }
            var cookie = httpContext.Request.Cookies[System.Web.Helpers.AntiForgeryConfig.CookieName];
            System.Web.Helpers.AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]);
        }
    }

然后,您只需在控制器中的方法上添加[ValidateHeaderAntiForgeryToken]。 但请注意,这是来自MVC 5,ASP.NET 4.5.2项目,因此您可能需要稍微更改它以适应.NET Core。 此外,我修改了此选项以在缺少令牌时返回JSON结果,如果您不处理错误响应并将其输出给用户,则可以删除该部分。 此属性核心部分的信用额为: https//nozzlegear.com/blog/send-and-validate-an-asp-net-antiforgerytoken-as-a-request-header

困难的部分是如何在纯Angular 2应用程序中不使用@Html.AntiForgeryToken()来生成AntiForgeryToken(无法访问.cshtml文件)。 我也在寻找答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM