ASP.NET Core-基于动态策略的授权

时间:2020-03-03 11:48:35

标签: asp.net asp.net-mvc asp.net-core asp.net-core-mvc asp.net-core-webapi

我正在开发一个相对较大的应用程序。我想在我的应用程序中实现权限级别授权。我已经开发了此代码,该代码仅可用于一个权限,但不适用于多个权限。

这是示例代码: 下面的枚举指示我的应用程序将提供的功能:

public enum CppFeature
{
    NotDefined = 0,

    DistributorManagement = 1,

    ChannelPartnerManagement = 2,
}

以下代码指示我的应用程序支持哪些权限:

public enum CppPermission
{
    NotDefined = 0,
    View = 1,
    Invite = 2,
    Deactivate = 3,
    List = 4,
    Edit = 5,
    Create = 6,
    Approve = 7,
}

最后,在数据库中创建一个映射,该映射说明哪些权限适用于哪个功能...

|------------------------|------------------|
|      Feature           |     Permission   |
|------------------------|------------------|
|  DistributorManagement |       View       |
|------------------------|------------------|
|  DistributorManagement |      Invite      |
|------------------------|------------------|
|ChannelPartnerManagement|      Create      |
|------------------------|------------------|

然后,用户可以创建动态角色并从映射中选择权限。

稍后,在我的代码中,我配置了以下自定义策略:

public class CppFeaturePermissionCheck
{
    public CppFeature Feature { get; set; }

    public List<CppPermission> Permission { get; set; }
}

public class CustomPolicyProvider : IAuthorizationPolicyProvider
{
    public CustomPolicyProvider (IOptions<AuthorizationOptions> options)
    {
        DefaultPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
    }

    public DefaultAuthorizationPolicyProvider DefaultPolicyProvider { get; }

    public Task<AuthorizationPolicy> GetPolicyAsync(string policyName)
    {
        if (!string.IsNullOrEmpty(policyName))
        {
            var policy = new AuthorizationPolicyBuilder();
            policy.AddRequirements(new CppAuthorizeRequirement(JsonConvert.DeserializeObject<List<CppFeaturePermissionCheck>>(policyName)));
            return Task.FromResult(policy.Build());
        }
        return DefaultPolicyProvider.GetPolicyAsync(policyName);
    }

    public Task<AuthorizationPolicy> GetDefaultPolicyAsync()
    {
        return DefaultPolicyProvider.GetDefaultPolicyAsync();
    }
}

public class CppAuthorizeRequirement : IAuthorizationRequirement
{
    public CppAuthorizeRequirement(List<CppFeaturePermissionCheck> userPermission)
    {
        UserPermissions = userPermission;
    }

    public List<CppFeaturePermissionCheck> UserPermissions { get; set; }
}

public class CppAuthorizeAttribute : AuthorizeAttribute
{
    public CppAuthorizeAttribute(CppFeature feature, CppPermission permission)
        : this(new List<CppFeaturePermissionCheck>()
        {
            new CppFeaturePermissionCheck()
            {
                Feature = feature,
                Permission = new List<CppPermission>()
                {
                    permission,
                },
            },
        })
    {
    }
    // This ctor doesn't work since attributes can only have primitive types as parameter.
    public CppAuthorizeAttribute(List<CppFeaturePermissionCheck> featurePermissions)
    {
        Policy = JsonConvert.SerializeObject(featurePermissions, Formatting.None);
    }
}

[CppAuthorize(CppFeature.ChannelPartnerManagement, CppPermission.View)]
[HttpPost("channelpartnerlist")]
public async Task<IActionResult> PartnerList([FromBody]ChannelPartnerListRequestModel_V1 model)
    {
        try
        {
            //some work.                
        }
        catch (CPPException ioe)
        {

        }
    }

问题是: 1.该属性不支持数组,列表或字典的参数类型,这将允许我指定多个权限

是否有更好的方法可以指定特定功能中的特定权限是否支持特定操作?

0 个答案:

没有答案