【问题标题】:IAuthorizationFilter not called every time不是每次都调用 IAuthorizationFilter
【发布时间】:2016-04-22 08:47:04
【问题描述】:

我们使用 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 的政策。正如我在堆栈跟踪中看到的那样,Identity 在检查CookieAuthenticationOptions 后试图在中间件的某处创建一个Microsoft.AspNet.Identity.SignInManager,我认为他正在尝试重新登录用户,但它没有检查我的过滤器?登录在我们的应用程序中非常特殊,所以我不想让 Identity 自动登录我们的用户。当身份验证 cookie 过期时,我可以重现此问题。 有任何想法吗 ?谢谢!

【问题讨论】:

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


    【解决方案1】:

    您还需要使TokenAuthorizationFilter 继承自AuthorizeAttribute 用于授权过滤器,并将其重命名为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));
    });
    

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

    【讨论】:

    • 我读到从AuthorizeAttribute继承不是一个好的解决方案,最好使用Policy。
    • 同意,但在这种情况下,您甚至不需要 IAuthorizationFilter,您只需在 Startup.cs 类services.AddAuthorization(options => options.AddPolicy("PolicyName", policy => { you add your requirements here })) 中配置服务时添加具有自定义(或不​​)要求的策略即可跨度>
    • 是的,你是对的。我们将令牌的验证从IAuthorizationFilter 移至CookieAuthenticationEvents,效果更好。谢谢你的帮助!
    【解决方案2】:

    我终于找到了问题所在。每 30 分钟,Identity 都会尝试通过 SecurityStamp 验证来验证用户,这会导致应用程序崩溃,因为它需要一个在验证时不存在的数据库连接。通过重新实现OnValidatePrincipal,我们在启动时取消了此验证:

    options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents { OnValidatePrincipal = (context) => Task.FromResult(0) };
    

    【讨论】:

      猜你喜欢
      • 2017-09-15
      • 2023-04-11
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 2013-03-10
      相关资源
      最近更新 更多