对角的WebAPI Asp.Net,在服务器上实现CSRF [英] Angular against Asp.Net WebApi, implement CSRF on the server

查看:360
本文介绍了对角的WebAPI Asp.Net,在服务器上实现CSRF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实施Angular.js一个网站,这是一个打击ASP.NET的WebAPI后端。

I'm implementing a website in Angular.js, which is hitting an ASP.NET WebAPI backend.

Angular.js有一些内置的功能,以帮助反CSRF保护。每个HTTP请求,它会寻找一个叫XSRF-TOKEN饼干,并提交一个名为X-XSRF-TOKEN标题。

Angular.js has some in-built features to help with anti-csrf protection. On each http request, it will look for a cookie called "XSRF-TOKEN" and submit it as a header called "X-XSRF-TOKEN" .

这依赖于Web服务器能够验证用户,然后检查传入的请求的X XSRF-TOKEN头之后设置XSRF-TOKEN的cookie。

This relies on the webserver being able to set the XSRF-TOKEN cookie after authenticating the user, and then checking the X-XSRF-TOKEN header for incoming requests.

借助角文档状态:

要充分利用这一点,你的服务器需要设置一个令牌叫XSRF-TOKEN的第一个HTTP GET请求一个JavaScript可读的会话cookie。在随后的非GET请求服务器可以验证cookie的比赛的X XSRF-TOKEN HTTP头,因此可以确保只有在域上运行的JavaScript都能读取的标记。令牌必须为每个用户唯一的,而且必须是可核查由服务器(以prevent中的JavaScript制作了自己的令牌)。我们建议令牌是用食盐以增加安全性您网站的验证cookie的摘要。

To take advantage of this, your server needs to set a token in a JavaScript readable session cookie called XSRF-TOKEN on first HTTP GET request. On subsequent non-GET requests the server can verify that the cookie matches X-XSRF-TOKEN HTTP header, and therefore be sure that only JavaScript running on your domain could have read the token. The token must be unique for each user and must be verifiable by the server (to prevent the JavaScript making up its own tokens). We recommend that the token is a digest of your site's authentication cookie with salt for added security.

我找不到这对ASP.NET的WebAPI任何很好的例子,所以我推出我自己的从各种渠道的帮助。我的问题是 - ?任何人都可以看到什么毛病code

I couldn't find any good examples of this for ASP.NET WebAPI, so I've rolled my own with help from various sources. My question is - can anyone see anything wrong with the code?

首先,我定义了一个简单的辅助类:

First I defined a simple helper class:

public class CsrfTokenHelper
{
    const string ConstantSalt = "<ARandomString>";

    public string GenerateCsrfTokenFromAuthToken(string authToken)
    {
        return GenerateCookieFriendlyHash(authToken);
    }

    public bool DoesCsrfTokenMatchAuthToken(string csrfToken, string authToken) 
    {
        return csrfToken == GenerateCookieFriendlyHash(authToken);
    }

    private static string GenerateCookieFriendlyHash(string authToken)
    {
        using (var sha = SHA256.Create())
        {
            var computedHash = sha.ComputeHash(Encoding.Unicode.GetBytes(authToken + ConstantSalt));
            var cookieFriendlyHash = HttpServerUtility.UrlTokenEncode(computedHash);
            return cookieFriendlyHash;
        }
    }
}

然后我在我的授权控制器下面的方法,我称之为后,我打电话FormsAuthentication.SetAuthCookie():

Then I have the following method in my authorisation controller, and I call it after I call FormsAuthentication.SetAuthCookie():

    // http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-(csrf)-attacks
    // http://docs.angularjs.org/api/ng.$http
    private void SetCsrfCookie()
    {
        var authCookie = HttpContext.Current.Response.Cookies.Get(".ASPXAUTH");
        Debug.Assert(authCookie != null, "authCookie != null");
        var csrfToken = new CsrfTokenHelper().GenerateCsrfTokenFromAuthToken(authCookie.Value);
        var csrfCookie = new HttpCookie("XSRF-TOKEN", csrfToken) {HttpOnly = false};
        HttpContext.Current.Response.Cookies.Add(csrfCookie);
    }

然后,我有一个自定义属性,我可以添加到控制器,使他们检查CSRF头:

Then I have a custom attribute which I can add to controllers to make them check the csrf header:

public class CheckCsrfHeaderAttribute : AuthorizeAttribute
{
    //  http://stackoverflow.com/questions/11725988/problems-implementing-validatingantiforgerytoken-attribute-for-web-api-with-mvc
    protected override bool IsAuthorized(HttpActionContext context)
    {
        // get auth token from cookie
        var authCookie = HttpContext.Current.Request.Cookies[".ASPXAUTH"];
        if (authCookie == null) return false;
        var authToken = authCookie.Value;

        // get csrf token from header
        var csrfToken = context.Request.Headers.GetValues("X-XSRF-TOKEN").FirstOrDefault();
        if (String.IsNullOrEmpty(csrfToken)) return false;

        // 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.
        return new CsrfTokenHelper().DoesCsrfTokenMatchAuthToken(csrfToken, authToken);
    }
}

最后,我清除CSRF令牌当用户注销:

Lastly, I clear the Csrf token when the user logs out:

HttpContext.Current.Response.Cookies.Remove("XSRF-TOKEN");

任何人都可以发现任何明显的(或不那么明显)的问题与方法?

Can anyone spot any obvious (or not-so-obvious) problems with that approach?

推荐答案

还没有遇到任何问题,指出了与code,所以我认为这个问题的回答。

Haven't had any problems pointed out with the code, so I consider the question answered.

这篇关于对角的WebAPI Asp.Net,在服务器上实现CSRF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆