@ Html.AntiForgeryToken() 呈现隐藏的输入
<input name="__RequestVerificationToken" type="hidden" value="GuiNIwhIJZjINHhuS_8FenaFDXIiaE" />
我如何才能获得令牌价值? 没有像这样丑陋的代码:
public static IHtmlString AntiForgeryTokenValue(this HtmlHelper htmlHelper) {
var field = htmlHelper.AntiForgeryToken().ToHtmlString();
var beginIndex = field.IndexOf("value=\"") + 7;
var endIndex = field.IndexOf("\"", beginIndex);
return new HtmlString(field.Substring(beginIndex, endIndex - beginIndex));
}
答案 0 :(得分:17)
MVC的反CSRF功能实际上依赖于两个令牌:一个是隐藏的表单元素,另一个是cookie。因此,Html.AntiForgeryToken()帮助程序不会返回HTML代码段。 它还有设置此cookie的副作用。请注意,cookie值和表单值不相等,因为它们各自编码不同的信息。
如果您使用AntiForgery.GetTokens API,此方法将返回原始令牌,而不是生成HTML代码段。此方法的参数是:
如果您使用此API手动生成Cookie和表单令牌,则需要调用AntiForgery.Validate的the corresponding overload以验证令牌。
答案 1 :(得分:12)
我意识到这个问题已经过时了,但根据我在这里阅读的内容,我想出了一个似乎对我有用的相当简单的解决方案。我在使用部分模板的AngularJS SPA上使用它,其中只有一部分涉及POST提交。
我把这段代码放在了视图的顶部:
@{
string cookieToken, formToken;
string oldCookieToken = Request.Cookies[AntiForgeryConfig.CookieName] == null ? null : Request.Cookies[AntiForgeryConfig.CookieName].Value;
AntiForgery.GetTokens( oldCookieToken, out cookieToken, out formToken );
if( oldCookieToken == null )
{
Request.Cookies.Add( new HttpCookie( AntiForgeryConfig.CookieName, cookieToken ) );
}
else
{
Request.Cookies[AntiForgeryConfig.CookieName].Value = cookieToken;
}
}
然后我需要表单的防伪令牌(例如,在ajax或angularjs POST中)我只需要包含&#39; @ formToken&#39;在标题中:
$http.post(route, JSON.stringify(args), {
headers: {
'@AntiForgeryConfig.CookieName': '@formToken',
'Content-Type': 'application/json; charset=utf-8',
},
});
请注意,因为在这个示例中,我希望从我的操作方法返回JSON数据,所以我还必须基于标题而不是表单字段实现防伪验证。在http://johan.driessen.se/posts/Updated-Anti-XSRF-Validation-for-ASP.NET-MVC-4-RC.有一篇很好的帖子。这是实施:
[AttributeUsage( AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = false, Inherited = true )]
public sealed class ValidateJsonAntiForgeryTokenAttribute
: FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization( AuthorizationContext filterContext )
{
if( filterContext == null )
{
throw new ArgumentNullException( "filterContext" );
}
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate( cookie != null ? cookie.Value : null,
httpContext.Request.Headers[AntiForgeryConfig.CookieName] );
}
}
以及它的使用方式:
[HttpPost]
[ValidateJsonAntiForgeryToken]
public JsonResult RecordVisit( VisitInfo info )
答案 2 :(得分:0)
这有点老了,但是我没有找到真正的答案。我四处张望,找到了解决方案。我需要在javascript对象中使用formtoken,因此该帮助器非常有用。
public static class AntiForgeryHtmlExtensions
{
public static string AntiForgeryFormToken(this HtmlHelper helper)
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
HttpContext.Current.Response.Cookies.Set(new HttpCookie(AntiForgeryConfig.CookieName, cookieToken));
return formToken;
}
}
如@Levi所述,调用GetTokens具有副作用,因此我们必须在返回令牌之前设置response-cookie。
答案 3 :(得分:0)
对于asp.net core使用依赖注入获取IAntiforgery然后调用GetAndStoreTokens
public class TestController
{
public TestController(IAntiforgery antiforgery)
{
var tokens = antiforgery.GetAndStoreTokens(HttpContext);
}
}