2

My Web APIs are accessed by Angular client hosted in Node process and hence I am generating anti forgery tokens as part of OAuth token generation and attach them as cookies for the response as shown below:

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

I see cookies being received by the client.

Then for subsequent calls, I include below headers:

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

As can be noted, I am including both cookieToken and formToken in the headers.

When client makes the call, I validate those tokens as shown below (this code is as per other SO people discussions):

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

This method fails with the below error

"Validation of the provided anti-forgery token failed. The cookie "__RequestVerificationToken" and the form field "__RequestVerificationToken" were swapped."

After this, I have tried swapping but getting below error:

"The provided anti-forgery token was meant for a different claims-based user than the current user."

I have looked at few people reporting similar errors: link but not sure about the solution. Can someone review the above code and let me know the error.

Note: I have used Fiddler for testing purposes.

Thanks

3 Answers3

0

this happens due to your static function call

public static void SetXsrfCookies(IOwinResponse response, DateTime expiresUtc)

either remove the static attribute from function or better use the function as async task

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

i had the same issue with webmethod (aspx) when multiple users called same function depending on the load and call the ids got swapped, change the static function to dynamic one,Hopefully this will work for you too

RAHUL S R
  • 1,569
  • 1
  • 11
  • 20
  • It has nothing to do with the static (I have changed the code and tested to confirm this). Also, it is not related to any load because I am doing developer testing with just one user. I believe there must be something else had helped you :-) – CHEMBETI ARAVIND Jul 24 '17 at 08:28
  • how are you awaiting the `response.Cookies.Append` ? – MattjeS Aug 23 '17 at 14:56
0

I check your code, and find some problems.

  1. You set someCookieToken in the request header, and set someFormToken in the cookie, so you indeed swap the cookie token and form token by mistake. You should set someCookieToken in cookie, and set someFormToken in the request header.
  2. You use the method AntiForgery.GetTokens to create the cookie token and form token, and I only find the code that you add them into Cookies, but I can not find the code how you set __RequestVerificationToken into request header. So I think the cookie token and form token you added in the request is not a correct pair.
Crazy Crab
  • 694
  • 6
  • 16
0

In your line of the code, "__RequestVerificationToken=someFormToken", change it to "RequestVerificationToken" or some other name. Since the Form token and cookie token both has the same name "__RequestVerificatioToken", you are getting the error.

Akhil Mathew
  • 1,571
  • 3
  • 34
  • 69
Abi rami
  • 9
  • 1