首页 > 解决方案 > 使用剃须刀页面覆盖 .net core 2 中的授权策略

问题描述

我有一个关于授权策略如何在 .net core 2 中重叠/被覆盖的问题。

基本上,我想设置一个策略,默认情况下,所有页面都需要管理员访问权限,然后某些部分也明确向普通用户开放。这样,默认情况下,任何新部分都会被锁定。

所以在服务设置部分我设置了策略:

 services.AddAuthorization(options =>
        {
            options.AddPolicy("ValidUser",
                policy => policy.RequireClaim("Type"));  //any valid user
            options.AddPolicy("AdministratorsOnly", 
                policy => policy.RequireClaim("Type",UserType.Administrator.ToString()));
        });

然后是剃须刀页面选项:

services.AddMvc()
.AddRazorPagesOptions(options =>
{
    options.Conventions.AuthorizeFolder("/","AdministratorsOnly");

    options.Conventions.AuthorizeFolder("/UserFolder", "ValidUsers"); 

});

但是,ValidUsers 策略不会覆盖上面设置的一揽子 AdministratorsOnly 策略。如果我在 /UserFolder 上使用 AllowAnonymousToFolder,那将否定管理员策略,但显然这不是我想要的。

如果我颠倒过来,让一揽子策略为 ValidUsers,而“覆盖”为 AdministratorsOnly,那么它就可以工作。但同样,不是我想要的。

有没有办法使这项工作?在这种情况下,文档的帮助不大。

是的,我知道我可以通过为管理页面设置管理文件夹并以这种方式锁定它们来到达我需要的位置。或任何数量的其他方法来确保安全。但是为了将来的参考,我真的很想知道当它们像这样重叠时策略是如何相互作用的。

标签: c#asp.net-corerazor-pages

解决方案


对于您的场景,覆盖授权策略是不合理的,您应该通过判断页面的应用程序根相对路径和用户的声明来自定义策略,如下所示:

services.AddAuthorization(options =>
        {
            options.AddPolicy("UserCheck", policy =>
            {
                policy.RequireAssertion(context =>
                {
                    var path = ((PageActionDescriptor)((ActionContext)context.Resource).ActionDescriptor).RelativePath;
                    if (path.StartsWith("/Pages")
                    && context.User.HasClaim("Type", UserType.Administrator.ToString()))
                    {
                        return true;
                    }
                    else if(path.StartsWith("/Pages/Admin/User")
                    && context.User.HasClaim(c => c.Type == "Type"))
                    {
                        return true;
                    }
                    return false;
                });
            });
        });
services.AddMvc()
            .AddRazorPagesOptions(options =>
            {
               //options.Conventions.AuthorizeFolder("/Admin/User", "UserCheck");

                options.Conventions.AuthorizeFolder("/Admin", "UserCheck");

            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

推荐阅读