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.
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.