1

I have a C# backend controller method that verify Google id token using the google auth. It works at first after deploying to my test server, but after awhile, it runs into a deadlock situation (I believe). There's no error, it just hangs at VerifyGoogleToken.

using Google.Apis.Auth;
using Google.Apis.Auth.OAuth2;

    [HttpPost]
    public async Task<string> VerifyGoogleToken(string Token)
    {
        var verifyUser = Task.Run(() => VerifyToken(Token).Result);
        await Task.WhenAll(verifyUser);
        string returnValue = verifyUser.Result.ToString();
        return returnValue;
    }

    private async Task<string> VerifyToken(string Token)
    {
        string ReturnValue = "InvalidToken";
        GoogleJsonWebSignature.Payload payload = await GoogleJsonWebSignature.ValidateAsync(Token);
        if (payload.HostedDomain == "mydomain.com" && payload.EmailVerified == true && payload.Audience.ToString() == ClientID && (payload.Issuer == "accounts.google.com" || payload.Issuer == "https://accounts.google.com"))
        {
            ReturnValue = "ValidToken";
        }
        return ReturnValue;
    }

I also tried just this:

[HttpPost]
public async Task<string> VerifyGoogleToken(string Token)
{
    string returnValue = await VerifyToken(Token)
    return returnValue;
}

private async Task<string> VerifyToken(string Token)
{
    string ReturnValue = "InvalidToken";
    GoogleJsonWebSignature.Payload payload = await GoogleJsonWebSignature.ValidateAsync(Token);
    if (payload.HostedDomain == "mydomain.com" && payload.EmailVerified == true && payload.Audience.ToString() == ClientID && (payload.Issuer == "accounts.google.com" || payload.Issuer == "https://accounts.google.com"))
    {
        ReturnValue = "ValidToken";
    }
    return ReturnValue;
}

Also this:

[HttpPost]
public string VerifyGoogleToken(string Token)
{
    string returnValue = VerifyToken(Token);
    return returnValue;
}

private async Task<string> VerifyToken(string Token)
{
    string ReturnValue = "InvalidToken";
    GoogleJsonWebSignature.Payload payload = await GoogleJsonWebSignature.ValidateAsync(Token);
    if (payload.HostedDomain == "mydomain.com" && payload.EmailVerified == true && payload.Audience.ToString() == ClientID && (payload.Issuer == "accounts.google.com" || payload.Issuer == "https://accounts.google.com"))
    {
        ReturnValue = "ValidToken";
    }
    return ReturnValue;
}

Nothing worked so far.

Any help is appreciated.

Wen W
  • 2,434
  • 1
  • 10
  • 15
  • Just guessing that you are having trouble debugging because of the Async call ValidateAsync which could be failing or hanging. Can you test with a Sync method call? – DaniDev Dec 13 '17 at 23:45
  • I don't think there's a sync version of the method (it's from google). Or are you asking if I tried wrapping the Async method with a Sync function call? – Wen W Dec 15 '17 at 17:50
  • yes. just for debugging purposes. – DaniDev Dec 15 '17 at 18:06
  • and (obviously) don't await the async call (to google) – DaniDev Dec 15 '17 at 18:08
  • Any luck? were you able to debug? – DaniDev Dec 15 '17 at 21:48
  • I'm not that familiar with wrapping the async function in sync, but isn't the code under "Also this:" it? – Wen W Dec 17 '17 at 04:45
  • Sorry, didn't notice your question until now. To answer your question: Yes, in your ("Also This") attempt you have "un-Asynced" the calling method VerifyGoogleToken. Can you try to do the same for VerifyToken. So you can follow the thread and see if you are retrieving "payload" – DaniDev Dec 19 '17 at 17:32
  • There's no sync version of GoogleJsonWebSignature.ValidateAsync that I'm aware of, so no, I can't un-async it. – Wen W Dec 25 '17 at 18:51
  • As far as running an Async Method Synchronistically (sync context) you may be able to use Task.Run(() => ........) please read the following for more in depth understanding: https://stackoverflow.com/questions/22628087/calling-async-method-synchronously – DaniDev Dec 28 '17 at 19:19
  • More importantly, I did a little research for you and found the following: https://stackoverflow.com/questions/44600214/using-google-api-googlejsonwebsignature-validateasync-in-server-call since I am not that familiar with GoogleJsonWebSignature.ValidateAsync and you don't have an error to refer to I am not sure this is your issue, but it suggests that you have t provide/use the context user in addition to the token (makes sense). this also provides another great resource for testing your asynch code: https://msdn.microsoft.com/en-us/magazine/dn818493.aspx – DaniDev Dec 28 '17 at 19:30
  • Thanks. I already read through and tried all the links you provided before submitting this question. I suspected this has something to do with the number of times I call the validation method, so I went ahead and rewrote a lot of my code to only call the validation once per connection. My code used to call the validation frequently (once every 30 seconds), and the method just stopped returning anything after awhile. – Wen W Dec 31 '17 at 02:58
  • "method just stopped returning anything after awhile..." Glad you were able to verify that. As originally it was "it runs into a deadlock situation "? – DaniDev Jan 02 '18 at 17:29

1 Answers1

0

I believe there's a limit on how many times you can call the validation, but I don't exactly know the limit. My code used to call validation every 30 seconds to do things like getting the user's ID/email etc.. This setup stopped working after a few hours. Since I rewrote the code to call the validation only a few times per connection, the validation have since been working properly.

Wen W
  • 2,434
  • 1
  • 10
  • 15