2

This stack overflow question by dbrunning (note - the question itself, not the answers), describes a neat way to merge AngularJS anti-XSRF techniques with a .Net back-end sending out static html (i.e. NOT using cshtml or other format where a token is inserted into the html by the server).

However, it is designed for Microsoft forms authentication.

Given the automatically generated startup.cs and App_Start files which generate when creating a new WebAPI Solution in Visual Studio, How and where would I put something into the OWIN pipeline (neatly) in order to add to the response cookie collection before the page is sent, and remove it on Authentication Sign out.

The application pool is currently .NET 4.6

Thank you.

Community
  • 1
  • 1
Brent
  • 4,611
  • 4
  • 38
  • 55

1 Answers1

2

No answers, so i'll sketch in my own results of reading around - I have yet to test properly, but the schema I am thinking of using is

in Startup.Auth replace app.UseCookieAuthentication with

app.UseCookieAuthentication(new CookieAuthenticationOptions { Provider = new AngularCoookieAuthProvider() });

AngularCookieAuthProvider.cs

using Microsoft.Owin.Security.Cookies;
using System.Web.Helpers;

public class AngularCookieAuthProvider: CookieAuthenticationProvider
{
    public const string AngularHeaderTokenName = "XSRF-TOKEN";
    public const string AngularCookieTokenName = "X-XSRF-TOKEN";
    public override void ResponseSignedIn(CookieResponseSignedInContext context)
    {
        SetAntiCsfrTokens(context.Response);
        base.ResponseSignedIn(context);
    }
    public override void ResponseSignOut(CookieResponseSignOutContext context)
    {
        context.Response.Cookies.Delete(AngularCookieTokenName);
        context.Response.Headers.Remove(AngularHeaderTokenName);
        base.ResponseSignOut(context);
    }
    internal static void SetAntiCsfrTokens(IOwinResponse response, string oldCookieToken=null)
    {
        string cookieToken;
        string formToken;
        AntiForgery.GetTokens(oldCookieToken, out cookieToken, out formToken);

        response.Cookies.Append(AngularCookieTokenName, cookieToken);
        response.Headers.Append(AngularHeaderTokenName, formToken);
    }
}

and our CheckCsrfHeaderAttribute.cs:

using System.Linq;
using System.Net.Http;
using System.Web.Helpers;
using System.Web.Http;
using System.Web.Http.Controllers;
public class CheckCsrfHeaderAttribute : AuthorizeAttribute
{
    //  http://stackoverflow.com/questions/11725988/problems-implementing-validatingantiforgerytoken-attribute-for-web-api-with-mvc
    protected override bool IsAuthorized(HttpActionContext context)
    {
        var owinContext = context.Request.GetOwinContext();
        var request = owinContext.Request;
        // get auth token from cookie
        var authCookie = request.Cookies[AngularCoookieAuthProvider.AngularCookieTokenName];
        var csrfToken = request.Headers.GetValues(AngularCoookieAuthProvider.AngularHeaderTokenName).FirstOrDefault();

        // Verify that csrf token was generated from auth token
        // Since the csrf token should have gone out as a cookie, only our site should have been able to get it (via javascript) and return it in a header. 
        // This proves that our site made the request.
        AntiForgery.Validate(csrfToken, authCookie);//should throw if a problem

        AngularCoookieAuthProvider.SetAntiCsfrTokens(owinContext.Response, authCookie);
        return true;
    }
}
Brent
  • 4,611
  • 4
  • 38
  • 55