IAuthorizationFilter 不是每次都调用

Chr*_*gax 1 c# asp.net-core-mvc asp.net-identity-3 asp.net-core

我们使用一个IAuthorizationFilter类来过滤所有请求,并检查身份验证 cookie 中是否仍然存在自定义用户声明(多租户应用程序)。这些信息对于应用程序的其余部分至关重要。如果这些信息不存在,我们将重定向到登录页面。

    public class TokenAuthorizationFilter : IAuthorizationFilter, IAsyncAuthorizationFilter
    {

        public TokenAuthorizationFilter()
        {
            // Some dependency injection ...
        }

        public void OnAuthorization(Microsoft.AspNet.Mvc.Filters.AuthorizationContext context)
        {
            CheckToken(context);
        }

        public Task OnAuthorizationAsync(Microsoft.AspNet.Mvc.Filters.AuthorizationContext context)
        {
            return CheckToken(context);
        }
}
Run Code Online (Sandbox Code Playgroud)

我们像这样注册我们的过滤器

    services.AddMvc(config =>
    {
        config.Filters.Add(typeof(TokenAuthorizationFilter));
    });
Run Code Online (Sandbox Code Playgroud)

我想要访问的控制器的操作非常简单:

[Authorize(Policy = "TokenValid")]
public class HomeController : AjaxBaseController
{
    public IActionResult Index()
    {
        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

我们甚至没有达到我们的政策AuthorizeAttribute。正如我在堆栈跟踪中看到的, Identity 在检查 a 后尝试Microsoft.AspNet.Identity.SignInManager在中间件中的某个位置创建一个CookieAuthenticationOptions,我假设他正在尝试重新登录用户,但它没有检查我的 Filter ?登录在我们的应用程序中非常特殊,所以我不想让 Identity 自动登录我们的用户。当身份验证 cookie 过期时,我可以重现此问题。有任何想法吗 ?谢谢 !

小智 5

您还需要为授权过滤器TokenAuthorizationFilter继承,并将其重命名为. 这将成为您可以调用的属性:AuthorizeAttributeTokenAuthorizationFilterAttribute[TokenAuthorizationFilter]

[TokenAuthorizationFilter]
public class HomeController : AjaxBaseController
{
    public IActionResult Index()
    {
        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

同时实现 IAuthorizationFilter 和 IAsyncAuthorizationFilter 时要小心,因为 ASP.NET Core 在这种情况下只会调用异步方法:如果不需要任何异步调用,则仅实现 IAuthorizationFilter 接口。

另外,如果您继续像这样注册过滤器:

services.AddMvc(config =>
{
    config.Filters.Add(typeof(TokenAuthorizationFilter));
});
Run Code Online (Sandbox Code Playgroud)

您会注意到,每个操作都会调用过滤器,因为它将强制每次调用授权过滤器,因此在这种情况下,您不需要在操作之上添加该属性。