每次都没有调用IAuthorizationFilter

时间:2016-04-22 08:47:04

标签: asp.net-core asp.net-core-mvc asp.net-identity-3

我们使用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);
        }
}

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

    services.AddMvc(config =>
    {
        config.Filters.Add(typeof(TokenAuthorizationFilter));
    });

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

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

我们甚至没有达到AuthorizeAttribute的政策。正如我在stacktrace中看到的那样,Identity在检查Microsoft.AspNet.Identity.SignInManager之后尝试在中间件的某处创建CookieAuthenticationOptions,我认为他正在尝试重新登录用户,但它没有检查我的过滤器?登录在我们的应用程序中非常特殊,所以我不想让Identity自动记录我们的用户。当身份验证cookie过期时,我可以重现此问题。 有任何想法吗 ?谢谢!

2 个答案:

答案 0 :(得分:3)

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

[TokenAuthorizationFilter]
public class HomeController : AjaxBaseController
{
    public IActionResult Index()
    {
        return View();
    }
}

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

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

services.AddMvc(config =>
{
    config.Filters.Add(typeof(TokenAuthorizationFilter));
});

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

答案 1 :(得分:0)

最后我发现了问题。每隔30分钟,Identity就会尝试通过SecurityStamp验证来验证用户,这会导致应用程序崩溃,因为它需要一个在验证时不存在的数据库连接。我们通过重新实现OnValidatePrincipal

来启动我们在启动时的验证
options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents { OnValidatePrincipal = (context) => Task.FromResult(0) };