ASP.net Identity从javascript发送AntiForgeryToken

hyp*_*erN 3 javascript asp.net asp.net-mvc angularjs asp.net-identity

使用ASP.net MVC 5来自帐户控制器和帐户视图.在Register视图中有行

@Html.AntiForgeryToken()
Run Code Online (Sandbox Code Playgroud)

以上寄存器控制器有属性:

[ValidateAntiForgeryToken]
Run Code Online (Sandbox Code Playgroud)

我决定使用JSON从javascript发送数据到服务器(我使用的是Angular和$ http.post方法).

我的问题是如何使用javascript发送此AntiForgeryToken并在控制器中验证它?

我应该包括更多安全措施吗?

Los*_*ter 8

AngularJS内置支持XSRF(AKA防伪)

XSRF是一种未经授权的站点可以获取用户私有数据的技术.Angular提供了一种对抗XSRF的机制.执行XHR请求时,$ http服务从cookie(默认情况下为XSRF-TOKEN)读取令牌并将其设置为HTTP头(X-XSRF-TOKEN).由于只有在您的域上运行的JavaScript才能读取Cookie,因此您的服务器可以确保XHR来自您域上运行的JavaScript.不会为跨域请求设置标头.

如果要利用此功能,则必须创建将创建和验证XSRF-TOKEN cookie的操作过滤器.这是我使用的简化版本.

AntiForgeryTokenCookieAttribute - 使用此属性添加XSRF-TOKEN cookie

/// <summary>
/// Create a XSRF token in the XSRF-TOKEN cookie which is automatically read by AngularJS
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class AntiForgeryTokenCookieAttribute : ActionFilterAttribute
{
    private readonly IAntiForgeryVerificationTokenStore _verificationTokenStore = new AntiForgeryVerificationTokenCookieStore(); //TODO: make configurable
    private const string CookieName = "XSRF-TOKEN"; //TODO: make configurable

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var oldVerificationToken = _verificationTokenStore.GetVerificationToken(filterContext.HttpContext.Request);

        string newVerificationToken;
        string newToken;
        AntiForgery.GetTokens(oldVerificationToken, out newVerificationToken, out newToken);

        if (newVerificationToken != null)
        {
            _verificationTokenStore.StoreVerificationToken(filterContext.HttpContext.Response, newVerificationToken);
        }

        filterContext.HttpContext.Response.Cookies.Add(new HttpCookie(CookieName, newToken));
    }
}
Run Code Online (Sandbox Code Playgroud)

ValidateAntiForgeryTokenHeaderAttribute

/// <summary>
/// Validate the XSRF token stored in the X-XSRF-TOKEN header.
/// If the header doesn't exist, look for the XSRF token in the from post.
/// 
/// Compatible with ValidateAntiForgeryTokenAttribute
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateAntiForgeryTokenHeaderAttribute : FilterAttribute, IAuthorizationFilter
{
    private readonly IAntiForgeryVerificationTokenStore _verificationTokenStore = new AntiForgeryVerificationTokenCookieStore(); //TODO: make configurable
    private const string TokenHeaderName = "X-XSRF-TOKEN"; //TODO: make configurable

    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var token = filterContext.HttpContext.Request.Headers[TokenHeaderName];
        if (token != null)
        {
            //validate the token stored in header
            var verificationToken = _verificationTokenStore.GetVerificationToken(filterContext.HttpContext.Request);
            if (verificationToken == null) { throw new HttpAntiForgeryException("Required verification token not found"); }
            AntiForgery.Validate(verificationToken, token);
        }
        else
        {
            //validate the token stored in form. Same as ValidateAntiForgeryTokenAttribute
            AntiForgery.Validate();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

IAntiForgeryVerificationTokenStore

public interface IAntiForgeryVerificationTokenStore
{
    string GetVerificationToken(HttpRequestBase request);
    void StoreVerificationToken(HttpResponseBase response, string token);
}
Run Code Online (Sandbox Code Playgroud)

AntiForgeryVerificationTokenCookieStore

public class AntiForgeryVerificationTokenCookieStore : IAntiForgeryVerificationTokenStore
{
    public string GetVerificationToken(HttpRequestBase request)
    {
        if (request == null) { throw new ArgumentNullException("request"); }

        var token = request.Cookies[AntiForgeryConfig.CookieName];
        return token != null ? token.Value : null;
    }

    public void StoreVerificationToken(HttpResponseBase response, string token)
    {
        if (response == null) { throw new ArgumentNullException("response"); }
        if (token == null) { throw new ArgumentNullException("token"); }

        response.Cookies.Add(new HttpCookie(AntiForgeryConfig.CookieName, token) { HttpOnly = true, Secure = AntiForgeryConfig.RequireSsl });
    }
}
Run Code Online (Sandbox Code Playgroud)