AJAX POST到Web API控制器和CSRF
AJAX POST到Web API控制器和CSRF
我基本上需要在我的Web API Controller中防止跨站请求伪造,这是MVC应用程序的一部分。我对任何想法都持开放态度。目前,我有一个MVC视图,使用ArcGIS for JavaScript API显示Esri地图。用户在地图上创建了一条路线,这条路线和它所穿越的各种要素可以通过AJAX POST保存。视图没有表单。这是因为我POST到服务器的所有数据都保存在内存中,不可见于屏幕上(或隐藏字段中)。\n所以,在我的MVC视图中,我有以下内容来获取防伪令牌:\n@functions{\npublic string GetTokenHeaderValue()\n{\n string cookieToken, formToken;\n AntiForgery.GetTokens(null, out cookieToken, out formToken);\n return cookieToken + \":\" + formToken;\n}\n}\n我在视图中有一个隐藏的输入框,但是意识到这是不好的,因为它同时具有与AntiForgery.Validation一起使用的“表单令牌”和cookie令牌:\n\n然后,在一个独立的JavaScript文件中(不是在视图中的脚本标签中),我对我的Web API Controller进行了Http POST。这是我将令牌添加到请求头的地方:\nvar headers = {};\nheaders[\'RequestVerificationToken\'] = $(\"#antiforgeryToken\").val();\n// Ajax POST to Web API Controller\n$.ajax({\n async: true,\n url: \'/api/RouteData\',\n type: \'POST\',\n headers: headers,\n data: requestData,\n dataType: \'json\',\n error: function (xhr, statusText, errorThrown) {\n console.log(\'Error saving route data! \' + errorThrown);\n },\n success: function (result) {\n }\n});\n注意:在请求体中进行POST的数据都保存在一个自定义的Dojo小部件中的内存中(因为页面使用ArcGIS for JavaScript显示Esri地图)。页面上没有表单,因为用户不输入数据。\n在服务器端的Web API Controller中将所有内容绑定在一起:\n[System.Web.Http.HttpPost]\n[ResponseType(typeof(RouteData))]\npublic async Task
原因:CSRF(跨站请求伪造)是一种攻击方式,攻击者通过欺骗用户在受信任的网站上执行非用户意愿的操作。如果Web API没有进行CSRF保护,攻击者可以通过在其他网站上发布一个带有恶意代码的表单来执行一些恶意操作,比如删除账户。
解决方法:可以通过使用防伪标记来保护Web API免受CSRF攻击。防伪标记是在服务器端生成的,通过在服务器响应中将标记发送给客户端,并在客户端发起请求时验证该标记是否有效来确保请求来自于预期的来源。
在ASP.NET MVC中,可以使用AntiForgeryToken方法生成防伪标记,并在表单中插入该标记。然后在服务器端使用ValidateAntiForgeryToken属性来验证防伪标记的有效性。
如果Web API和前端应用程序位于不同的域上,可以考虑以下解决方案:
1. 使用CORS(跨源资源共享)来允许跨域请求,并在服务器端进行验证。
2. 将防伪标记作为请求头或查询参数发送到Web API,并在服务器端进行验证。
3. 使用其他身份验证方式,如基于令牌的身份验证,而不是依赖于防伪标记。
以上是解决CSRF问题的原因和方法。