我基本上需要在我的Web API控制器中防止跨站点请求伪造,这是MVC应用程序的一部分.我对任何想法持开放态度.此时,我有一个MVC视图,它使用ArcGIS for JavaScript API显示Esri地图.用户在地图上创建路线,并且可以通过AJAX POST保存其穿过的路线和各种功能.视图没有表单.这是因为我POST到服务器的所有数据都在内存中,而且在屏幕上(或在隐藏字段中)不可见.
@functions{
public string GetTokenHeaderValue()
{
string cookieToken,formToken;
AntiForgery.GetTokens(null,out cookieToken,out formToken);
return cookieToken + ":" + formToken;
}
}
我在View中有这个隐藏的输入,但是意识到这很糟糕,因为它既有’form token’,也有与AntiForgery.Validation一起使用的cookie令牌:
然后,在一个单独的JavaScript文件中(不在View中的脚本标记中),我正在对我的Web API Controller进行Http POST.这是我将令牌添加到请求标头的位置:
var headers = {};
headers['RequestVerificationToken'] = $("#antiforgeryToken").val();
// Ajax POST to Web API Controller
$.ajax({
async: true,url: '/api/RouteData',type: 'POST',headers: headers,data: requestData,dataType: 'json',error: function (xhr,statusText,errorThrown) {
console.log('Error saving route data! ' + errorThrown);
},success: function (result) {
}
});
注意:在正文中获取POST的数据全部位于自定义Dojo小部件的内存中(因为该页面使用ArcGIS for JavaScript显示Esri地图).由于用户未输入数据,因此页面上没有表单.)
在Web API控制器中将它们全部绑定在服务器端:
[System.Web.Http.HttpPost]
[ResponseType(typeof(RouteData))]
public async Taskviewmodel routeDataVM)
{
try
{
HttpRequestMessage httpRequestMessage = HttpContext.Current.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
ValidateRequestHeader(httpRequestMessage);
}
catch (Exception ex)
{
_logger.Log(LogLevel.Error,ex,ex.Message);
throw;
}
// Now that we know user is who they say they are,perform update
}
void ValidateRequestHeader(HttpRequestMessage request)
{
string cookieToken = "";
string formToken = "";
IEnumerable
AntiForgery.Validate验证令牌.
我见过这个SO post,它给了我一些想法,但并没有为我解决这个问题.很多信用也归功于post on ASP.net.
是什么让我与众不同(我认为)是我的JavaScript在一个单独的文件中,无法调用服务器端的Razor函数来获取防伪标记,对吧?关于如何在没有表格的情况下防范CSRF的任何想法?
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. CSRF attacks specifically target state-changing requests,not theft of data,since the attacker has no way to see the response to the forged request. With a little help of social engineering (such as sending a link via email or chat),an attacker may trick the users of a web application into executing actions of the attacker’s choosing.
如果未受保护,以下将是针对您的Web API的CSRF攻击的示例:
通过从受感染的网站发布此表单,如果您使用cookie身份验证(作为示例)作为管理帐户登录到您的Web API,则它可能能够从您的系统中删除帐户.
发生这种情况是因为当您重定向到API时,您的浏览器会通过针对yourapi.com域存储的cookie进行传递,从而对用户进行身份验证并执行所需的操作.此攻击向量不同于使用(例如,承载令牌)对您的API进行身份验证,因为第三方不知道此令牌.
正如您所说并实施的那样,使用防伪令牌可以防止这种情况,因为生成的令牌在Web响应中发送到客户端,然后由客户端发回并经过验证以确保它是来自我们期望的某个地方的允许请求.与承载令牌一样,第三方可能不知道您在服务器请求中发送的令牌.在这方面,你所实现的是绝对正确的,并将令牌传递给客户端就是我们期望它的工作方式.
在ASP.NET MVC(无API)中,这实现如下:
..和验证的服务器端:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Action(MyModel model)
{
// ..
}
当你调用@ Html.AntiForgeryToken()时,该方法都设置一个cookie(包含cookie令牌)并将其发送到客户端,并生成一个< input type =“hidden”..>标记发送给客户端.然后将它们发送回来并验证服务器端.
有了这些知识,您可以看到您对发送“cookie令牌”和“表单令牌”的担忧是没有根据的,因为无论如何都会发生这种情况.
我确实看到你担心的原因,但你试图缓解的似乎是中间人(MitM)攻击而不是CSRF.要解决大部分MitM攻击,您应确保您的站点/ API都通过HTTPS运行.如果您的客户仍然容易受到MitM攻击,那么您的API可能是攻击者最不关心的问题.