0

Is there a way to access HttpContext from a request handler? I added a filter to my (minimal API) endpoint to validate the API key, coming from the request headers. Upon successful validation I need the value to Generate JWT for subsequent requests.

Is there a workaround to this? Need a code sample.

Aweda
  • 323
  • 1
  • 4
  • 15

2 Answers2

2

You may be able to use HttpContextAccessor, which allows custom components to access the HttpContext via dependency injection. Your IRequestHandler can then inject IHttpContextAccessor.

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-7.0#access-httpcontext-from-custom-components

For other framework and custom components that require access to HttpContext, the recommended approach is to register a dependency using the built-in Dependency Injection (DI) container. The DI container supplies the IHttpContextAccessor to any classes that declare it as a dependency in their constructors:

builder.Services.AddHttpContextAccessor();

Be sure to consider the lifetime of your IRequestHandler if you're using scoped information such as the HttpContext user, and consider applying the requisite data from the user into the request DTO itself rather than having the handler take a dependency on an ambient scoped piece of information, as that reduces some of the value of abstracting the handlers in the first place.

Adam
  • 3,339
  • 1
  • 10
  • 15
1

Using Carter, it would be something like this (but it is just matter of using equivalent for non-Carter implementation):

public interface ITokenGrabber
{
    void SetToken(string token);
    string GetToken();
}

public class TokenGrabber : ITokenGrabber
{
    private string _token;

    public string GetToken() => _token;

    public void SetToken(string token) => _token = token;
}

public class SampleFilter : IEndpointFilter
{
    public ValueTask<object> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
    {
        var grabber = context.HttpContext.RequestServices.GetService<ITokenGrabber>();

        string token = context.HttpContext.Request.Headers["Authorization"];
            
        grabber.SetToken(token);

        return next(context);
    }
}

    public class SomeHandler
        : IRequestHandler<SomeRequest>
    {
        private readonly ITokenGrabber _grabber;

        public GetAllExercisesQueryHandle(ITokenGrabber grabber)
        {
            _grabber = grabber;
        }

        public Task Handle(SomeRequestrequest, CancellationToken cancellationToken)
        {
            Console.WriteLine(_grabber.GetToken());
            
            return ...
        }
    }

Make sure ITokenGrabber is properly configured with scoped lifetime:

builder.Services.AddScoped<ITokenGrabber, TokenGrabber>();