I wanted to have my API support AOT so I've decided to move away from MVC Controllers.
I don't like the minimal API approach though so I've decided to write my own middleware to handle the requests and responses manually (with my own code generation but that's not important).
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<MyRequestResponseMiddleware>();
The problem is that authentication/authorization stopped working. HttpContext.User
is not configured, claims are empty, IsAuthenticated
is always false even after the authentication/authorization middleware.
public async Task InvokeAsync(HttpContext context)
{
Debug.WriteLine(context.User.Identity.IsAuthenticated); //always false
}
I guess it makes sense. I use two auth schemas and multiple policies and I want to manually handle what policy needs to be applied to a different request path like this:
//EXAMPLE
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Path.Value == "/auth-request")
{
var result = authenticationService.Authenticate("policyName");
//if authentication fails, return 401
//otherwise user is authenticated
//process request as usual
}
}
But I have no idea how to do this.
How is MVC doing it? How is minimal api doing it?
How to check for authentication/authorization configured with methods like AddJwtBearer
,AddScheme
,AddAuthorization
,AddPolicy
etc. in custom request/response middleware?
Okay that was easier than I expected.
using Microsoft.AspNetCore.Authentication;
namespace MyProject;
public class MyMiddleware(IAuthorizationService authorizationService)
{
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Path.Value == "/auth-request")
{
var authenticateResult = await context.AuthenticateAsync("myScheme");
if (authenticateResult.Succeeded)
{
//authenticated
context.User = authenticateResult.Principal;
var authorizeResult = await authorizationService.AuthorizeAsync(context.User, "myPolicy");
if (authorizeResult.Succeeded)
{
//authenticated and authorized
}
}
}
}
}