使用Angular客户端防止CSFR,.NET webAPI& OWIN身份验证

时间:2016-01-18 22:56:33

标签: owin csrf

This stack overflow question by dbrunning(注意 - 问题本身,而不是答案),描述了一种将AngularJS反XSRF技术与.Net后端发送静态html(即不使用cshtml或其他格式)合并的简洁方法其中令牌被服务器插入到html中。)

但是,它是专为Microsoft表单身份验证而设计的。

鉴于在Visual Studio中创建新的WebAPI解决方案时生成的自动生成的startup.cs和App_Start文件,我将如何以及在何处将内容放入OWIN管道(整齐地)以便在之前添加到响应cookie集合中页面已发送,并在身份验证注销时将其删除。

应用程序池目前是.NET 4.6

谢谢。

1 个答案:

答案 0 :(得分:2)

没有答案,所以我将在自己的阅读结果中草绘 - 我还没有正确测试,但我正在考虑的模式是

在Startup.Auth中将app.UseCookieAuthentication替换为

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

和我们的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;
    }
}