sf.
sf.

Reputation: 25480

asp.net core check route attribute in middleware

I'm trying to build some ASP.Net core middleware.

It needs see if the current route is marked as [Authorize].

eg:

public async Task Invoke(HttpContext context)
{
    if(context.Request.Path.Value.StartsWith("/api"))
    {
        // check if route is marked as [Authorize]
        // and then do some logic
    }

    await _next.Invoke(context);
}

Does anyone know how this could be achieved or if it's even possible?

If not, what would be a good alternative approach?

Upvotes: 26

Views: 14845

Answers (5)

OMM
OMM

Reputation: 9

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseMiddleware<UserManagementAuthorizationMiddleware>();

@Koja Please see this I have this sequence but it is also returns null.

Upvotes: 0

Koja
Koja

Reputation: 900

HansElsen's answer is correct, but I would like to add some things to note about it:

  1. You can use the extension method context.GetEndpoint() which is exactly the same as context.Features.Get<IEndpointFeature>().Endpoint
  2. The endpoint will always be null if you set up your middleware before calling app.UseRouting() in your Startup.cs:

Don't do:

app.UseMiddleware<MyMiddleware>();
app.UseRouting();

Do:

app.UseRouting();
app.UseMiddleware<MyMiddleware>();

Upvotes: 21

HansElsen
HansElsen

Reputation: 1753

I believe it can be achieved in a middleware class via:

var hasAuthorizeAttribute = context.Features.Get<IEndpointFeature>().Endpoint.Metadata
                .Any(m => m is AuthorizeAttribute);

Upvotes: 40

sf.
sf.

Reputation: 25480

Just self-answering to close the question.

Doesn't seem like it's possible to do this as it's too early in the pipeline.

Upvotes: 4

M&#233;toule
M&#233;toule

Reputation: 14472

Without knowing exactly what you want to achieve, it's a bit tricky to answer, but I suggest you have a look at the controller filters : https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters

I put together an example:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .AddMvcOptions(options => options.Filters.Insert(0, new CustomFilter()));
}

CustomFilter.cs

public class CustomFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        if(context.HttpContext.Request.Path.Value.StartsWith("/api"))
        {
            var controllerInfo = context.ActionDescriptor as ControllerActionDescriptor;
            var hasAuthorizeAttr = controllerInfo.ControllerTypeInfo.CustomAttributes.Any(_ => _.AttributeType == typeof(AuthorizeAttribute));
        }
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        // NOP
    }
}

Upvotes: 8

Related Questions