Ответ 1
Добавить в ASP.NET MVC Просмотр, который обслуживает AngularJS SPA, скажем
Views\Home\Index.cshtml
, HTML-помощник, который генерируетAntiForgeryToken
.
@Html.AntiForgeryToken();
Настройте AngularJS, чтобы передать выше сформированный
AntiForgeryToken
в качестве заголовка запроса.
angular.module('app')
.run(function ($http) {
$http.defaults.headers.common['X-XSRF-Token'] =
angular.element('input[name="__RequestVerificationToken"]').attr('value');
});
Создайте собственный фильтр веб-API для проверки всех не-GET-запросов (
PUT
,PATCH
,POST
,DELETE
).Это предполагает, что все ваши запросы
GET
безопасны и не нуждаются в защите.
Если это не так, удалите исключениеif (actionContext.Request.Method.Method != "GET")
.
using System;
using System.Linq;
using System.Net.Http;
using System.Web.Helpers;
using System.Web.Http.Filters;
namespace Care.Web.Filters
{
public sealed class WebApiValidateAntiForgeryTokenAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(
System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext == null)
{
throw new ArgumentNullException("actionContext");
}
if (actionContext.Request.Method.Method != "GET")
{
var headers = actionContext.Request.Headers;
var tokenCookie = headers
.GetCookies()
.Select(c => c[AntiForgeryConfig.CookieName])
.FirstOrDefault();
var tokenHeader = string.Empty;
if (headers.Contains("X-XSRF-Token"))
{
tokenHeader = headers.GetValues("X-XSRF-Token").FirstOrDefault();
}
AntiForgery.Validate(
tokenCookie != null ? tokenCookie.Value : null, tokenHeader);
}
base.OnActionExecuting(actionContext);
}
}
}
Зарегистрируйте вновь созданный фильтр как глобальный, в
Global.asax.cs
.
private static void RegisterWebApiFilters(HttpFilterCollection filters)
{
filters.Add(new WebApiValidateAntiForgeryTokenAttribute());
}
В качестве альтернативы, если вы не хотите добавлять этот фильтр глобально, вы можете поместить его только в определенные действия веб-API, например, это
[WebApiValidateAntiForgeryToken]
Это, конечно, по определению менее безопасно, так как всегда есть шанс, что вы забудете применить этот атрибут к нужному ему действию.
Также обратите внимание, что для доступа к пространству имен System.Web.Http
у вас должен быть пакет Microsoft.AspNet.WebApi.Core
. Вы можете установить его через NuGet с помощью Install-Package Microsoft.AspNet.WebApi.Core
.
Этот пост был сильно вдохновлен в этом сообщении в блоге.