Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 ASP.NET Core AntiForgeryToken

I have an Angular2 app. It is running within ASP.NET 5 (Core).
It makes Http calls to the controller which is working fine.

But now I need to establish Cross Site Scripting projection.

How do I generate a new token on each Http request and then subsequently perform the AntiForgeryToken check in Angular2 apps?

Note: My data forms in Angular are not produced from an MVC view but entirely written in Angular2 and call web services only.

All the examples I have seen are out dated and do not work / do not work fully.

How do I integrate AntiForgeryToken checks in Angular2 against ASP.NET 5 where forms are pure Angular?

Thanks.

like image 758
DanAbdn Avatar asked Mar 29 '16 21:03

DanAbdn


People also ask

What is AntiForgeryToken in asp net core?

In ASP.NET Core, @Html. AntiForgeryToken() is applied for preventing cross-site request forgery (XSRF/CSRF) attacks.

What is AntiForgeryToken C#?

AntiForgeryToken()Generates a hidden form field (anti-forgery token) that is validated when the form is submitted. C# Copy. public System.Web.Mvc.

What is anti forgery token in angular?

The AntiForgeryToken is used to prevent cross-site request forgery (CSRF) attacks and this article will illustrate how to configure and use the AntiForgeryToken during AngularJS AJAX request in ASP.Net Core MVC. Download Code Sample.


2 Answers

A custom action filter is not necessary. It can all be wired up in 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);
  });

  (...)
}

Then all you need in your controllers is the [ValidateAntiForgeryToken] decorator wherever you want to enforce that a token is provided.

For reference, I found this solution here - AspNet AntiForgery Github Issue 29.

like image 150
DanO Avatar answered Oct 21 '22 03:10

DanO


I am using a action filter to send the request tokens. Simply apply it to the actions you want a new antiforgery token, e.g. Angular2 SPA, WebAPI action, etc.

[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 { }); 
}

Register the attribute in Startup, and configure Antiforgery service to read the request token form "X-XSRF-TOKEN" header.

public class Startup
{
    // ...

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

        services.AddScoped<AngularAntiForgeryTokenAttribute>();
        services.AddAntiforgery(options =>
        {
            options.HeaderName = "X-XSRF-TOKEN";
        });
    }
}
like image 42
fszlin Avatar answered Oct 21 '22 02:10

fszlin