A2D JS框架 - Web API CSRF保护实现
这次自己实现了类似jQuery中ajax调用的方法,并且针对RESTFul进行了改造和集成,实现的A2D AJAX接口如下:
$.ajax.RESTFulGetCollection("/api/Users", function (data) { alert(data[5].FirstName); }); $.ajax.RESTFulGetOne("/api/Users/1", function (data) { alert(data.UserID); }); $.ajax.RESTFulDelete("/api/Users/1", function (data) { alert("deleted"); }); $.ajax.RESTFulPost("/api/Users", { UserID: 0, FirstName: "aa", LastName: "bbb"}, function (data) { alert("added"); }); $.ajax.RESTFulPut("/api/Users/1", { UserID: 0, FirstName: "aa", LastName: "bbb"}, function (data) { alert(data); });
我们再深入点,要是别人恶意访问Delete的url呢?比如CSRF攻击。普通webform或者普通MVC方式可以比较方便的阻止攻击, 方法参考这篇文章的A8章节
答案:使用http header来传递token。步骤如下(以A2D与ASP.NET WEBAPI配合为例):
@functions{ public string TokenHeaderValue() { string cookieToken, formToken; AntiForgery.GetTokens(null, out cookieToken, out formToken); return cookieToken + ":" + formToken; } } $.ajax.Config.CSRFToken="@TokenHeaderValue()"; //把生成的token赋给A2D的ajax $.ajax.RESTFulGetCollection("/api/Users", function (data) { alert(data[5].FirstName); }); $.ajax.RESTFulGetOne("/api/Users/1", function (data) { alert(data.UserID); }); $.ajax.RESTFulDelete("/api/Users/1", function (data) { alert("deleted"); }); $.ajax.RESTFulPost("/api/Users", { UserID: 0, FirstName: "aa", LastName: "bbb"}, function (data) { alert("added"); }); $.ajax.RESTFulPut("/api/Users/1", { UserID: 0, FirstName: "aa", LastName: "bbb"}, function (data) { alert(data); });
然后编写webapi的handler:
public class CSRFHandler : DelegatingHandler { protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { if (request.Method == HttpMethod.Post || request.Method == HttpMethod.Put || request.Method == HttpMethod.Delete)//这里csrf只针对这3种请求才会验证 { ValidateRequestHeader(request); } return base.SendAsync(request, cancellationToken); } private void ValidateRequestHeader(HttpRequestMessage request) { string cookieToken = ""; string formToken = ""; IEnumerable<string> tokenHeaders; if (request.Headers.TryGetValues("A2D-CSRFToken", out tokenHeaders)) //这个header值要和A2D框架中的一致 { string[] tokens = tokenHeaders.First().Split(':'); if (tokens.Length == 2) { cookieToken = tokens[0].Trim(); formToken = tokens[1].Trim(); } } AntiForgery.Validate(cookieToken, formToken); } }
最后在WebApiConfig中注册这个handler
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MessageHandlers.Add(new CSRFHandler()); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
好了,都搞定了。
code download.
自省推动进步,视野决定未来。
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai