1

There is a simple ASP.NET app as an event handler Server:

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services
    .AddWebPubSub(options => options.ServiceEndpoint = new ServiceEndpoint(WebPubSubConnectionString))
    .AddWebPubSubServiceClient<WebPubSubHub>();

WebApplication app = builder.Build();

app.MapWebPubSubHub<WebPubSubHub>("/eventhandler");
app.Run();

The Azure Web PubSub has the following configuration of Webhook URL:

enter image description here

I need to protect this endpoint somehow /eventhandler because it's public and anyone can call it. One of the options that Azure suggests is using a simple authentication code. enter image description here

Help me to understand where I should verify that code in my ASP.NET app?

Let's say I configured the URL template in WPS like

https://a9e5-92-253-212-316.ngrok-free.app/eventhandler?code=RRRRR

then in the server code

app.MapWebPubSubHub<WebPubSubHub>("/eventhandler?code=RRRRR")

result is exception

Microsoft.AspNetCore.Routing.Patterns.RoutePatternException: 'The literal section 'eventhandler?code=RRRRR' is invalid. Literal sections cannot contain the '?' character.'

Darkside
  • 470
  • 3
  • 20

1 Answers1

1

One possible way is to use AddEndpointFilter

app.MapWebPubSubHub<WebPubSubHub>("/eventhandler").AddEndpointFilter(new ApiKeyFilter(builder.Configuration));

the implementation could look like this:

public class ApiKeyFilter : IEndpointFilter
{
    private readonly string _apiKey;

    public ApiKeyFilter(IConfiguration configuration)
    {
        _apiKey = configuration.GetValue<string>("ApiKey");
    }

    public async ValueTask<object> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
    {
        if (!context.HttpContext.Request.Query.TryGetValue("code", out var extractedApiKey))
        {
            return Results.Unauthorized();
        }

        if (!_apiKey.Equals(extractedApiKey))
        {
            return Results.Unauthorized();
        }

        return await next(context);
    }
}

another option is to use

app.MapWebPubSubHub<WebPubSubHub>`("/eventhandler").RequireAuthorization(builder => builder.AddRequirements(new ApiKeyRequirement))

where ApiKeyRequirement is your implementation of IAuthorizationRequirement

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116