I'm looking at SS code in github and I can't to find any equivalent to ValidateAntiForgeryToken because I don't want to reinvent the wheel and I'd like to reuse as much as possible the SS framework, I think that a solution could be to create a custom RequestFilterAttribute, any other ideas?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
It looks like that wheel has already been invented:
https://github.com/ServiceStack/ServiceStack/tree/master/src/ServiceStack/Html/AntiXsrf
回答2:
I ended up by creating a requestFilterAttibute with similar capabilities of the asp.net mvc
this is the code I've done so far:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public class ValidateHttpAntiForgeryToken : RequestFilterAttribute
{
public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
{
try
{
if (IsAjaxRequest(req))
ValidateRequestHeader(req);
else
AntiForgery.Validate();
}
catch (Exception ex)
{
res.StatusCode = 403;
res.StatusDescription = ex.Message;
}
}
private void ValidateRequestHeader(IHttpRequest req)
{
var cookie = req.Cookies.FirstOrDefault(c => c.Value.Name.Contains(AntiForgeryConfig.CookieName));
if (cookie.Value == null)
{
throw new HttpAntiForgeryException(String.Format("Missing {0} cookie", AntiForgeryConfig.CookieName));
}
IEnumerable<string> xXsrfHeaders = req.Headers.GetValues("__RequestVerificationToken");
if (xXsrfHeaders == null || !xXsrfHeaders.Any())
throw new HttpAntiForgeryException("Missing X-XSRF-Token HTTP header");
AntiForgery.Validate(cookie.Value.Value, xXsrfHeaders.FirstOrDefault());
}
private static bool IsAjaxRequest(IHttpRequest request)
{
IEnumerable<string> xRequestedWithHeaders = request.Headers.GetValues("X-Requested-With");
if (xRequestedWithHeaders != null && xRequestedWithHeaders.Any())
{
string headerValue = xRequestedWithHeaders.FirstOrDefault();
if (!String.IsNullOrEmpty(headerValue))
{
return String.Equals(headerValue, "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
}
}
return false;
}
}