Asp.Net核心授权政策

时间:2020-01-10 16:32:10

标签: c# asp.net-core

我偶然发现了有关新的Asp.Net Core授权策略的讨论文章。许多人批评该功能,但是当我在Web API中处理授权问题时,我发现它对我很有用。

我的Web应用有两个部分。同一项目中的API和网络应用程序。它还有两个DbContextDbContext1DbContext2;因此有两组身份用户。对于每两个用户,一个用户必须从另一个DbContext1进行身份验证才能访问另一个DbContex2。另外,DbContext2DbContext1初始化。我已经使授权与使用Cookie身份验证的Web应用程序一起正常工作,但是授权不适用于API。 我使用授权属性[Authorize(Roles="AdminDb2,SupervisorDb2")]设计了API控制器 但后来没有任何效果。出现问题了。我的默认身份存储使用DbContext1作为其身份存储,这意味着DbContext2的用户无法获得授权。是的,我使用JWT Authentication的事实也无济于事。另外,我还必须转到我的startup文件并执行以下操作

public void ConfigureServices(IServiceCollection services)
{
   services.AddIdentity<Db1User, Db1Role>()
                .AddEntityFrameworkStores<DbContext1>()
                .AddRoleManager<Db1RoleManager>()
                .AddSignInManager<Db1SignInManager>()
                .AddUserManager<DbAuthenticationManager>()
                .AddDefaultTokenProviders()
                .AddDefaultUI(Microsoft.AspNetCore.Identity.UI.UIFramework.Bootstrap4);
}

,还通过致电添加了第二个身份

services.AddIdentityCore<Db2User>()

没有任何效果。 经过数天的思考,虽然授权不起作用,但我发现Identity存储正在尝试使用DbContext1对用户进行授权。好的,现在我明白了。我现在发现基于策略的授权很有用。 现在,我在startup文件中完成了此操作

services.AddAuthorization(options =>
            {
                options.AddPolicy("SuperPolicy", pOptions =>
                {
                    pOptions.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
                    pOptions.Requirements.Add(new ApiRequirement("Admin,SuperAdmin"));
                });
}

然后我必须使用首选的方法来处理这样的授权

public class ApiRequirement : IAuthorizationRequirement
    {
        public string[] Requirements { get; }
        public ApiRequirement(params string[] requirements)
        {
            Requirements = requirements;
        }

    }

public class ApiAuthorizeHandler: AuthorizationHandler<ApiRequirement>
    {
        private readonly TokenValidator _tokenValidator;
        public ApiAuthorizeHandler(TokenValidator tokenValidator)
        {
            _tokenValidator = tokenValidator;
        }

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ApiRequirement requirement)
        {
            AuthorizationFilterContext filterContext = (AuthorizationFilterContext)context.Resource;
            string authToken = filterContext.HttpContext.Request.Headers["Authorization"];
            TokenValidator validationResult = _tokenValidator.ValidateToken(authToken);
            bool result = validationResult.IsInRole(requirement.Requirements);
            if (result)
            {
                context.Succeed(requirement);
                context.User.AddIdentity(validationResult.ClaimsPrincipal.Identities.First());
                return Task.CompletedTask;
            }
            context.Fail();
            return Task.CompletedTask;
        }
    }

有了这个,我不需要编写新的授权过滤器

然后我用通常的Authorize过滤器设计了控制器

[Authorize(Policy="SuperPolicy")]
public class MyController : ControllerBase
{

}

我发现此方法的一件事是,每当您想向属性添加角色或要求时,都必须转到注入授权的启动文件,并执行options.AddPolicy().....这样的启动工作文件开始看起来不整洁。但是,如果不是那样的话,那么它随时随地都很好。 我发现这种共享想法可能会有所帮助。

0 个答案:

没有答案