Web API Antiforgery标记被交换

时间:2017-07-24 05:08:09

标签: cookies asp.net-web-api antiforgerytoken

我的Web API由Node进程中托管的Angular客户端访问,因此我生成反伪造令牌作为OAuth令牌生成的一部分,并将它们作为响应的cookie附加,如下所示:

public static void SetXsrfCookies(IOwinResponse response, DateTime expiresUtc)
    {
        string cookieToken;
        string formToken;

        AntiForgery.GetTokens("", out cookieToken, out formToken);

        response.Cookies.Append(AntiForgeryConfig.CookieName, cookieToken,
            new CookieOptions()
            {
                HttpOnly = true /* we want JavaScript clients to read this cookie*/,
                Expires = expiresUtc
            });

        response.Cookies.Append("FORM-TOKEN", formToken,
            new CookieOptions()
            {
                HttpOnly = true /* we want JavaScript clients to read this cookie*/,
                Expires = expiresUtc
            });
    }

我看到客户收到了cookies。

然后对于后续调用,我包含以下标题:

Authorization: Bearer someOAuthToken
Content-Type: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36     (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Cache-Control: no-cache
__RequestVerificationToken: someCookieToken
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: Logout=true; __RequestVerificationToken=someFormToken

可以注意到,我在标题中包含了cookieToken和formToken。

当客户拨打电话时,我会验证这些令牌,如下所示(此代码与其他SO人讨论一样):

var headers = actionContext.Request.Headers;
var cookie = headers.GetCookies()
                    .Select(c => c[AntiForgeryConfig.CookieName])
                    .FirstOrDefault();
var aspNetMvcRequestVerificationToken = headers.GetValues(AntiForgeryConfig.CookieName).FirstOrDefault();
AntiForgery.Validate(cookie != null ? cookie.Value : null,  aspNetMvcRequestVerificationToken);

此方法因以下错误而失败

  

“对提供的防伪令牌的验证失败。交换了cookie”__RequestVerificationToken“和表单字段”__RequestVerificationToken“。”

在此之后,我尝试了交换但得到以下错误:

  

“提供的防伪令牌适用于与当前用户不同的基于声明的用户。”

我看过几个报告类似错误的人:link但不确定解决方案。有人可以查看上面的代码,让我知道错误。

注意:我使用Fiddler进行测试。

由于

3 个答案:

答案 0 :(得分:0)

这是由于您的静态函数调用

而发生的
public static void SetXsrfCookies(IOwinResponse response, DateTime expiresUtc)

从函数中删除静态属性或更好地将该函数用作异步任务

public async static void SetXsrfCookies(IOwinResponse response, DateTime expiresUtc)
    {
        string cookieToken;
        string formToken;

        AntiForgery.GetTokens("", out cookieToken, out formToken);

        response.Cookies.Append(AntiForgeryConfig.CookieName, cookieToken,
            new CookieOptions()
            {
                HttpOnly = true /* we want JavaScript clients to read this cookie*/,
                Expires = expiresUtc
            });

       await response.Cookies.Append("FORM-TOKEN", formToken,
            new CookieOptions()
            {
                HttpOnly = true /* we want JavaScript clients to read this cookie*/,
                Expires = expiresUtc
            });
    } 

我遇到了webmethod(aspx)同样的问题,当多个用户根据负载调用相同的函数并调用id进行交换时,将静态函数更改为动态函数,希望这对你也有用

答案 1 :(得分:0)

我检查你的代码,发现一些问题。

  1. 您在请求标头中设置了 someCookieToken ,并在Cookie中设置了 someFormToken ,因此您确实错误地交换了Cookie令牌和表单令牌。您应该在Cookie中设置 someCookieToken ,并在请求标头中设置 someFormToken
  2. 您使用方法 AntiForgery.GetTokens 来创建Cookie令牌和表单令牌,我只找到您将它们添加到Cookie中的代码,但我找不到代码如何设置< strong> __ RequestVerificationToken 到请求标头中。所以我认为您在请求中添加的cookie令牌和表单令牌不是正确的配对。

答案 2 :(得分:0)

在您的代码行"__RequestVerificationToken=someFormToken"中,将其更改为"RequestVerificationToken"或其他名称。由于表格标记和Cookie标记都具有相同的名称"__RequestVerificatioToken",因此您收到错误。