我有一个由 ASP.NET MVC* 应用程序托管的 AngularJS 单页应用程序(SPA)。 后端是 ASP.NET Web
Api
。 *
我想通过在 ASP.NET MVC* 部分中生成一个,并将其传递给 AngularJS ,然后让 Web Api 验证从后续
AngularJS 调用中接收到的内容,来保护它免受 CSRF 攻击。AntiForgeryToken
AntiForgeryToken
***
“跨站点请求伪造(CSRF)是一种攻击,它迫使最终用户在当前经过身份验证的Web应用程序上执行不需要的操作。CSRF攻击专门针对状态更改请求而不是数据盗窃,因为攻击者无法看到对伪造请求的响应。借助社会工程学的一点帮助(例如通过电子邮件或聊天发送链接),攻击者可能会欺骗Web应用程序的用户执行攻击者选择的操作。如果受害者是普通用户,则成功的CSRF攻击可以迫使用户执行状态更改请求,例如转账,更改其电子邮件地址等。如果受害者是管理帐户,CSRF可能会破坏整个Web应用程序。”
-开放式Web应用程序安全项目(OWASP)
添加到服务 AngularJS SPA 的 ASP.NET MVC 视图中 ,例如,生成的HTML帮助器 。
__Views\Home\Index.cshtml``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');
});
创建自定义 的Web 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());
}
另外,如果您不想在全局范围内添加此过滤器,则可以仅将其放在某些Web API操作上,例如
[WebApiValidateAntiForgeryToken]
当然,从定义上讲,这是不太安全的,因为您总是会忘记将属性应用于需要它的操作。
另外,请注意,您必须具有Microsoft.AspNet.WebApi.Core
包才能访问System.Web.Http
名称空间。您可以使用NuGet通过NuGet安装它Install- Package Microsoft.AspNet.WebApi.Core
。
这篇文章受到了这篇博客文章的极大启发。