Mih*_*scu 37 c# asp.net-mvc asp.net-web-api angularjs
我有一个由ASP.NET MVC应用程序托管的AngularJS单页面应用程序(SPA).
后端是ASP.NET Web Api.
我想通过在ASP.NET MVC部分中生成一个,将其传递给AngularJS,然后让Web Api验证从后续AngularJS调用接收到的内容来保护它免受CSRF攻击.AntiForgeryTokenAntiForgeryToken
"跨站点请求伪造(CSRF)是一种攻击,它会强制最终用户在当前对其进行身份验证的Web应用程序上执行不需要的操作.CSRF攻击专门针对状态更改请求,而不是数据被盗,因为攻击者无法查看对伪造请求的响应.通过社交工程的一些帮助(例如通过电子邮件或聊天发送链接),攻击者可以欺骗Web应用程序的用户执行攻击者选择的操作.如果受害者是普通用户,则成功的CSRF攻击可以强制用户执行状态更改请求,例如转移资金,更改其电子邮件地址等.如果受害者是管理帐户,CSRF可能会破坏整个Web应用程序."
- 开放式Web应用程序安全项目(OWASP)
Mih*_*scu 56
添加到为AngularJS SPA提供服务的ASP.NET MVC 视图中,比如生成的HTML帮助器 .
Views\Home\Index.cshtmlAntiForgeryToken
@Html.AntiForgeryToken();
Run Code Online (Sandbox Code Playgroud)
配置AngularJS通过产生上述
AntiForgeryToken的请求报头.
angular.module('app')
.run(function ($http) {
$http.defaults.headers.common['X-XSRF-Token'] =
angular.element('input[name="__RequestVerificationToken"]').attr('value');
});
Run Code Online (Sandbox Code Playgroud)
创建自定义的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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
将新创建的过滤器注册为全局过滤器
Global.asax.cs.
private static void RegisterWebApiFilters(HttpFilterCollection filters)
{
filters.Add(new WebApiValidateAntiForgeryTokenAttribute());
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您不希望全局添加此过滤器,则只能将其放在某些Web API操作上,如下所示
[WebApiValidateAntiForgeryToken]
Run Code Online (Sandbox Code Playgroud)
当然,这在定义上不太安全,因为总是有可能忘记将属性应用于需要它的动作.
另请注意,您必须拥有该Microsoft.AspNet.WebApi.Core包才能访问System.Web.Http命名空间.你可以通过NuGet安装它Install-Package Microsoft.AspNet.WebApi.Core.
这篇文章深受这篇博文的启发.