'How to validate Hangouts Chat webhook token in C#
I am working on a pretty simple chat bot with an ASP.NET webhook to process responses. I am not having any issues sending or receiving messages, but I am a little bit stuck on validating the Bearer token in the Authorization header in order to validate that the incoming request has come from Google.
I have included the Google.Apis.Auth API version 1.55. It has the functionality that should do this validation. Of course the documentation does not give a .NET example, but from what I can gather, it should look like this:
try
{
string token = "token here";
SignedTokenVerificationOptions stvo = new SignedTokenVerificationOptions()
{
TrustedAudiences = { "my project id" },
TrustedIssuers = { "[email protected]" },
CertificatesUrl = "https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]"
};
JsonWebSignature.Payload r = await JsonWebSignature.VerifySignedTokenAsync(token, stvo);
return true;
}
catch (InvalidJwtException)
{
return false;
}
My issue is that I am getting an exception from deep inside the API where it looks like it is processing the certificates from Google. I don't think I have much influence over this bit!
System.ArgumentNullException: Value cannot be null.
Parameter name: source
at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
at Google.Apis.Auth.SignedTokenVerification.CertificateCacheBase.<GetCertificatesAsync>d__5.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis.Auth\SignedTokenVerification.cs:line 246
at Google.Apis.Auth.SignedTokenVerification.<GetCertificatesAsync>d__6.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis.Auth\SignedTokenVerification.cs:line 203
at Google.Apis.Auth.SignedTokenVerification.<VerifyRS256TokenAsync>d__4`2.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis.Auth\SignedTokenVerification.cs:line 110
at Google.Apis.Auth.SignedTokenVerification.<VerifySignedTokenAsync>d__3`2.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis.Auth\SignedTokenVerification.cs:line 102
at Google.Apis.Auth.JsonWebSignature.<VerifySignedTokenAsync>d__1`1.MoveNext() in C:\Apiary\2021-09-08.15-52-39\Src\Support\Google.Apis.Auth\JsonWebSignature.cs:line 61
at GroupHandler.<>c__DisplayClass0_0.<<ProcessRequest>b__0>d.MoveNext() in D:\IIS\Sites\Test\Google\BotVerify.ashx:line 31
Is this the right approach? Or am I missing something totally obvious? :) Joel
Solution 1:[1]
It should be the standard service account authorization.
You need Google.Apis.Auth and Google.Apis.HangoutsChat.v1 packages.
public class HangoutsAuth
{
public static string[] scopes = { "https://www.googleapis.com/auth/chat.bot" };
private static GoogleCredential GetCredential(string pathToServiceAccountKeyFile, string[] scopes)
{
// Load the Service account credentials and define the scope of its access.
return GoogleCredential.FromFile(pathToServiceAccountKeyFile)
.CreateScoped(scopes);
}
}
Just call it with
var service = HangoutsAuth.GetService(PathToKeyFile, { "https://www.googleapis.com/auth/chat.bot" });
var response = await service.Spaces.Messages.Create(body, "spaces/AAAA2CiqVDM").ExecuteAsync();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |