在AngularJS中使用$ http提交ASP.NET MVC CSRF令牌

时间:2016-10-07 04:23:39

标签: asp.net angularjs asp.net-mvc csrf angularjs-http

我正在开发一个ASP.NET MVC Web应用程序。我正在使用AngularJS。但由于CSRF验证,我在向服务器提交表单时遇到问题。首先,我是AngularJS的新手。

在AngularJS中,我在按钮点击事件

上提交这样的表格
angular.module('loginApp', ['ui.bootstrap', 'blockUI']).controller('loginController', function ($scope) {

    $scope.loginFormData = { }

    $scope.submitLoginForm = function()
    {
        $http.post("url", $scope.loginFormData, function (response) {

        })
    }
});

在服务器端,我进行CSRF验证以形成帖子

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<JsonResult> Login(LoginViewModel model)
        {
            //Do other stuff
        }

这是我的表单HTML:

            @Html.AntiForgeryToken()
            <div class="lock-container">
                <div class="panel panel-default text-center paper-shadow" data-z="0.5">
                    <div class="panel-body">
                        <div class="form-group">
                            <div class="form-control-material">
                                <input class="form-control" ng-model="username" type="text" placeholder="Username">
                                @Html.LabelFor(x => x.UserName)
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="form-control-material">
                                <input class="form-control" ng-model="password" type="password" placeholder="Enter Password">
                                @Html.LabelFor(x=>x.Password)
                            </div>
                        </div>

                        <button ng-click="submitLoginForm()" class="btn btn-primary">Login <i class="fa fa-fw fa-unlock-alt"></i></button>
                    </div>
                </div>
            </div>

实际上它不是一种形式。我只是基本上用Ajax提交数据。您注意到顶部的@ Html.AntiForgeryToken()。当我在浏览器中检查时,我可以看到这样。

enter image description here

我想要做的是我想获得该令牌值并发送如下的$ http帖子。

$http.post("url",{ "_RequestVerificationToken": $scope.csrfToken }, function (response) {

        })

如果我像上面那样发送,csrf验证将在服务器上成功。我怎样才能实现它AngularJS?

3 个答案:

答案 0 :(得分:0)

您可以在标头中传递这些值,而不是正文内容。这可以针对该模块全局完成。请参阅以下链接。

angular.module('app')
.run(function ($http) {
$http.defaults.headers.common['X-XSRF-Token'] =
    angular.element('input[name="__RequestVerificationToken"]').attr('value');

});

请参阅此链接

AngularJS Web Api AntiForgeryToken CSRF

https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

答案 1 :(得分:0)

将令牌添加到FormData

 var formData = new FormData();
    formData.append("__RequestVerificationToken", token);
    formData.append("UserName", $scope.kullaniciAdi);
    formData.append("Password", $scope.sifre);

    $http({
        method: 'POST',
        url: '/Login/Login',
        data: formData,
        transformRequest: angular.identity, 
        headers: { 'Content-Type': undefined }

    }).then(function successCallback(response) {



    }, function errorCallback(response) {

    });

答案 2 :(得分:0)

要使csrf验证在服务器上成功进行,您需要在服务器端进行一些修改。

您可以在服务器端创建自定义过滤器属性,以验证您的防伪令牌。

创建一个类,并从System.Web.MVC提供的 ActionFilterAttribute 继承它。确保不要使用Web API命名空间。

using System;
using System.Web.Helpers;
using System.Web.Mvc;

namespace CustomFilters.Web.Filters
{
    public class MVCAntiForgeryTokenValidatorAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (filterContext.HttpContext.Request.HttpMethod != "GET")
            {
                var header = filterContext.HttpContext.Request.Headers.Get("_RequestVerificationToken");

                var cookieName = AntiForgeryConfig.CookieName; // this also same as the _RequestVerificationToken
                var tokenCookie = filterContext.HttpContext.Request.Cookies.Get(cookieName);

                var tokenHeader = string.Empty;
                if (!string.IsNullOrEmpty(headers))
                {
                    tokenHeader = header;
                }

                AntiForgery.Validate(tokenCookie != null ? tokenCookie.Value : null, tokenHeader);
            }

            base.OnActionExecuting(filterContext);
        }
    }
}

然后您需要使用上面创建的自定义属性修改方法

[HttpPost]
[AllowAnonymous]
[MVCAntiForgeryTokenValidator]
public async Task<JsonResult> Login(LoginViewModel model)
{
    //Do other stuff
}

然后您完成了。当您的方法被angularJs服务方法击中时,在执行类方法之前。它将首先验证防伪令牌。