asp html表单没有csrf保护,Web API CSRF保护实现

这次自己实现了类似jQuery中ajax调用的方法,并且针对RESTFul进行了改造和集成,实现的A2D AJAX接口如下:

67d0865f17d9be527254bf8a8ff6c5b4.gif

$.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); });

67d0865f17d9be527254bf8a8ff6c5b4.gif

我们再深入点,要是别人恶意访问Delete的url呢?比如CSRF攻击。普通webform或者普通MVC方式可以比较方便的阻止攻击, 方法参考这篇文章的A8章节

答案:使用http header来传递token。步骤如下(以A2D与ASP.NET WEBAPI配合为例):

67d0865f17d9be527254bf8a8ff6c5b4.gif

@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); });

67d0865f17d9be527254bf8a8ff6c5b4.gif

然后编写webapi的handler:

67d0865f17d9be527254bf8a8ff6c5b4.gif

public class CSRFHandler : DelegatingHandler

{

protected override System.Threading.Tasks.Task 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 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);

}

}

67d0865f17d9be527254bf8a8ff6c5b4.gif

最后在WebApiConfig中注册这个handler

67d0865f17d9be527254bf8a8ff6c5b4.gif

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 }

);

}

}

67d0865f17d9be527254bf8a8ff6c5b4.gif

好了,都搞定了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值