0

I am implementing webhook using asp.net core 3.1 webhook package. This is a custom webhook poc and I need to expose this webhook to external users. During runtime I am facing below error and unable to solve it.

What can I try next?

Error:

Unable to find WebHook filters for the 'jr4o27tr2r472' receiver. Add the required configuration by calling a receiver-specific method that calls 'Microsoft.Extensions.DependencyInjection.IMvcBuilder.AddWebHooks' or 'IMvcCoreBuilder.AddWebHooks' in the application startup code. For example, call 'IMvcCoreBuilder.AddGitHubWebHooks' to configure a minimal GitHub receiver.

When I hit this url (http://localhost:49846/api/webhooks/incoming/jr4o27tr2r472/teleported), I am getting this issue in eventviewer.

Evenviewer exception log

Note: I have added required webhook services as part of configurationservice method.

public static class UnicornServiceCollectionSetup
{
    public static void AddUnicornServices(IServiceCollection services)
    {
        WebHookMetadata.Register<UnicornMetadata>(services);
        services.AddSingleton<UnicornSignatureFilter>();
    }
}
public static class UnicornMvcCoreBuilderExtensions
{
    public static IMvcCoreBuilder AddUnicornWebHooks(this IMvcCoreBuilder builder)
    {
        UnicornServiceCollectionSetup.AddUnicornServices(builder.Services);
        return builder.AddWebHooks();
    }
}
public class UnicornMetadata : WebHookMetadata, IWebHookFilterMetadata
{
    private readonly UnicornSignatureFilter _verifySignatureFilter;

    public UnicornMetadata(UnicornSignatureFilter verifySignatureFilter)
        : base(UnicornConstants.ReceiverName)
    {
        _verifySignatureFilter = verifySignatureFilter;
    }
    public override WebHookBodyType BodyType => WebHookBodyType.Json;

    public void AddFilters(WebHookFilterMetadataContext context)
    {
        context.Results.Add(_verifySignatureFilter);
    }
}
public class UnicornSignatureFilter : WebHookVerifySignatureFilter,
                                   IAsyncResourceFilter
{
    private readonly byte[] _secret;
    public UnicornSignatureFilter(//IOptions<UnicornConfig> options,
                                  IConfiguration configuration,
                                  IHostingEnvironment hostingEnvironment,
                                  ILoggerFactory loggerFactory)
         : base(configuration, hostingEnvironment, loggerFactory)
    {
        //_secret = Encoding.UTF8.GetBytes(options.Value.SharedSecret);
        _secret = Encoding.UTF8.GetBytes("secret");
    }

    public override string ReceiverName => UnicornConstants.ReceiverName;

    public async Task OnResourceExecutionAsync(ResourceExecutingContext context,
                                               ResourceExecutionDelegate next)
    {
        if (context == null) throw new ArgumentNullException(nameof(context));
        if (next == null) throw new ArgumentNullException(nameof(next));

        var request = context.HttpContext.Request;
        if (!HttpMethods.IsPost(request.Method))
        {
            await next();
            return;
        }

        var errorResult = EnsureSecureConnection(ReceiverName, request);
        if (errorResult != null)
        {
            context.Result = errorResult;
            return;
        }

        var header = GetRequestHeader(request,
                                      UnicornConstants.SignatureHeaderName,
                                      out errorResult);
        if (errorResult != null)
        {
            context.Result = errorResult;
            return;
        }

        byte[] payload;
        using (var ms = new MemoryStream())
        {
            HttpRequestRewindExtensions.EnableBuffering(request);
            await request.Body.CopyToAsync(ms);
            payload = ms.ToArray();
            request.Body.Position = 0;
        }

        if (payload == null || payload.Length == 0)
        {
            context.Result = new BadRequestObjectResult("No payload");
            return;
        }

        var digest = FromBase64(header, UnicornConstants.SignatureHeaderName);
        var secretPlusJson = _secret.Concat(payload).ToArray();

        using (var sha512 = new SHA512Managed())
        {
            if (!SecretEqual(sha512.ComputeHash(secretPlusJson), digest))
            {
                context.Result =
                    new BadRequestObjectResult("Signature verification failed");
                return;
            }
        }

        await next();
    }
}

Note: I am attaching source code in this webhookpoc.

halfer
  • 19,824
  • 17
  • 99
  • 186
V. Periyasamy
  • 99
  • 2
  • 10

0 Answers0