Conditionally use Middleware Only On Endpoints That Have Authorize Attributes

Viewed 2133

I have writted a piece of middleware that I only want to run on Authenticated endpoints.

So Basically I want it in my implementation to only trigger when a controller or action is marked with [Authorize]. Any controller action that does not require authhorization should not require my middleware to trigger.

I've found the UseWhen functionality but the best i've managed is that the middleware only triggers once a user is authenticated. However if will still trigger on all endpoints after the user has signed in.

Here is my current conditional.

        app.UseWhen(context => context.User.Identity.IsAuthenticated, appBuilder =>
        {
            appBuilder.UseAutomaticallyRefreshTokenMiddleware();
        });

I think i just need to change that context check, but not exactly sure what to replace it with.

3 Answers

The middlewares get registered to the pipeline based on the condition and the registrations are done only at startup. The registrations are not modified afterwards. Once they are a part of the pipeline, they are a part of the pipeline. One thing you can do is to customize the Authorize attribute. Inherit the Authorize attribute, and then inside that run the logic you are running inside your middleware.

ASP.NET Core 3.0 enables this with endpoint routing, this can't be accomplished before that because routing decisions and endpoint selection happens much later than when the middleware pipeline runs.

For your requirement, you could try IActionFilter instead of middleware.

  1. TokenRefrehFilter

    public class TokenRefrehFilter : IActionFilter
    {
        public void OnActionExecuted(ActionExecutedContext context)
        {
        }
    
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //check whether action is authorized attribute
            var isAuthorizedAction = context.Filters.Any(f => f.GetType() == typeof(AuthorizeFilter));
        }
    }
    
  2. Register TokenRefrehFilter

    services.AddMvc(options => {
        options.Filters.Add(typeof(TokenRefrehFilter));
    })
    SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    

    For this way, TokenRefrehFilter will run for controller request, and you could check isAuthorizedAction with True for the action needs to refreh the token.

Related