Skip to content

Instantly share code, notes, and snippets.

@PeterKottas
Last active August 29, 2019 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PeterKottas/d83906865a42f521586523fd54e7a6dc to your computer and use it in GitHub Desktop.
Save PeterKottas/d83906865a42f521586523fd54e7a6dc to your computer and use it in GitHub Desktop.
Attribute that helps with verifying Impala webhooks in dot net core
public static class ImpalaHeaderContants
{
public const string XImpalaSignature = "X-Impala-Signature";
}
public class ImpalaConfigDTO
{
public string ApiKey { get; set; }
public string WebhookSecret { get; set; }
}
public class ImpalaWebhookVerificationAttribute : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var config = context.HttpContext.RequestServices.GetService<IOptionsSnapshot<ImpalaConfigDTO>>().Value;
var strContent = await context.HttpContext.Request.GetRawBodyStringAsync();
context.HttpContext.Request.Headers.TryGetValue(ImpalaHeaderContants.XImpalaSignature, out var headers);
var xImpalaSignature = headers.FirstOrDefault();
var actualXImpalaSignature = GetXImpalaSignature(strContent, config.WebhookSecret);
if (actualXImpalaSignature != xImpalaSignature)
{
var logger = context.HttpContext.RequestServices.GetService<ILogger<ImpalaWebhookVerificationAttribute>>();
logger.LogWarning(string.Format("Unverified webhook call Body=[{0}] Hash=[{1}]", strContent, xImpalaSignature));
context.Result = (context.Controller as Controller).StatusCode(403);
}
else
{
await next();
}
}
private static string GetXImpalaSignature(string text, string key)
{
ASCIIEncoding encoding = new ASCIIEncoding();
var textBytes = encoding.GetBytes(text);
var keyBytes = encoding.GetBytes(key);
byte[] hashBytes;
using (HMACSHA256 hash = new HMACSHA256(keyBytes))
{
hashBytes = hash.ComputeHash(textBytes);
}
return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
}
}
@PeterKottas
Copy link
Author

Make sure to configure options, something along the lines of:

services.Configure<ImpalaConfigDTO>(Configuration.GetSection("Impala:Plugin"));

Then you just put the Attribute on method or controller.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment