FernanJC
FernanJC

Reputation: 55

Use HttpClient within middleware pipeline?

I am working on an API project with ASP.NET Core and I have to consume a custom OAuth service (also an ASP.NET Core) the company owns. That service should be called on every request made to the API, to validate that the user is authorize to use that resource, so I thought I could create a Middleware on the API that would handle that request to the OAuth service.

My problem is that I am still learning C# and ASP.NET Core and, I am not sure if whether or not that could be accomplished. I did some Googling, but I couldn't find examples with HttpClient calls done on a Middleware. I wonder if someone could give me a hint on if whether or not I am going on the right road or, if that is considered bad practice, and that there are better ways of accomplish it.

Upvotes: 3

Views: 7240

Answers (1)

Kahbazi
Kahbazi

Reputation: 15005

You need to write a custom authentication scheme and add it to your Authentications in ConfigureServices

Basically you need to implement AuthenticationHandler and inject HttpClient

public class CustomAuthHandler : AuthenticationHandler<CustomAuthOptions>
{


    public const string SchemeName = "CustomSchemeName";
    private readonly HttpClient _httpclient;

    public LocalAccessTokenValidationHandler(IOptionsMonitor<LocalAccessTokenValidationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock,  HttpClient httpclient)
        : base(options, logger, encoder, clock)
    {
        _httpclient= httpclient;
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // use _httpclient here and authenticate request and return AuthenticateResult
    }

And then add this to your authentication services

services.AddAuthentication(CustomAuthHandler.SchemeName) // setting CustomAuthHandler as the default
        .AddScheme<CustomAuthOptions, CustomAuthHandler>(CustomAuthHandler.SchemeName); 

Register HttpClient as a Singleton:

services.AddSingleton(new HttpClient());

Then you need to make sure all your controllers are marked as [Authorize].

Check this blog for more details. Check this filters for an idea on how to mark all controllers as authorized globally. This way you do not have to mark each controller with [Authorize] attribute.

Upvotes: 5

Related Questions