有条件地仅在具有授权属性的端点上使用中间件

Conditionally use Middleware Only On Endpoints That Have Authorize Attributes

我写了一个中间件,我只想 运行 在经过身份验证的端点上。

所以基本上我希望它在我的实现中仅在控制器或操作标记为 [Authorize] 时触发。任何不需要授权的控制器操作都不应该需要我的中间件来触发。

我找到了 UseWhen 功能,但我所管理的最好的是中间件仅在用户通过身份验证后触发。但是,如果在用户登录后仍会在所有端点上触发。

这是我当前的条件。

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

我想我只需要更改上下文检查,但不确定用什么替换它。

中间件根据条件注册到管道,注册仅在启动时完成。之后不会修改注册。一旦它们成为管道的一部分,它们就是管道的一部分。您可以做的一件事是自定义 Authorize 属性。继承 Authorize 属性,然后在 运行 中间件中 运行 的逻辑。

ASP.NET Core 3.0 通过端点路由实现了这一点,这在此之前无法完成,因为路由决策和端点选择发生的时间比中间件管道运行时要晚得多。

根据您的要求,您可以尝试 IActionFilter 而不是中间件。

  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. 注册TokenRefrehFilter

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

    对于这种方式,TokenRefrehFilter 将 运行 用于控制器请求,您可以检查 isAuthorizedActionTrue 是否需要刷新令牌的操作。