Отправка токена ASP.NET MVC CSRF с $http в AngularJS

Я разрабатываю веб-приложение ASP.NET MVC. Я использую 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() вверху. Когда я проверяю в браузере, я вижу это.

введите здесь описание изображения

Что я хочу сделать, так это получить значение этого токена и отправить сообщение $http, как показано ниже.

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

        })

Если я отправлю, как указано выше, проверка csrf будет успешной на сервере. Как я могу добиться этого с помощью AngularJS?


person Wai Yan Hein    schedule 07.10.2016    source источник


Ответы (3)


Чтобы проверка csrf прошла успешно на сервере, вам необходимо внести некоторые изменения на стороне сервера.

вы можете создать настраиваемый атрибут фильтра на стороне сервера для проверки вашего токена защиты от подделки.

Создайте класс и унаследуйте его от ActionFilterAttribute, который предоставляется System.Web.MVC. Не используйте пространства имен веб-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, прежде чем выполнять метод класса. Сначала он проверит токен защиты от подделки.

person AshanMG    schedule 10.06.2020

Вы можете передавать эти значения в заголовках вместо содержимого тела. Это можно сделать глобально для этого модуля. См. ссылки ниже.

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

person Thanigainathan    schedule 07.10.2016
comment
Когда я добавляю эту строку, $http.defaults.headers.common['X-XSRF-Token'] = angular.element('input[name=__RequestVerificationToken]').attr('value'); }); угловой js не работает. - person Wai Yan Hein; 07.10.2016

Добавить токен в 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) {

    });
person Ufuk Aydın    schedule 30.10.2018