09获取权限源码阅读记录

类关系图

类关系图

属于Volo.Abp解决方案的类:

  • PermissionDefinitionManager

属于Volo.Abp.PermissionManagement解决方案的类:

  • PermissionsController
  • PermissionAppService
  • PermissionManager
  • PermissionManagementProvider
  • EfCorePermissionGrantRepository

属于Volo.Abp.Identity解决方案的类:

  • UserPermissionManagementProvider
  • RolePermissionManagementProvider

PermissionDefinitionManage

用于提供系统中定义的权限定义

PermissionManager

权限管理类

获取权限方法:

    public virtual async Task<MultiplePermissionWithGrantedProviders> GetAsync(
        string[] permissionNames, 
        string providerName,
        string providerKey)
    {
        var permissions = new List<PermissionDefinition>();
        var undefinedPermissions = new List<string>();
        // 获取并检查系统定义的权限
        foreach (var permissionName in permissionNames)
        {
            var permission = await PermissionDefinitionManager.GetOrNullAsync(permissionName);
            if (permission != null)
            {
                permissions.Add(permission);
            }
            else
            {
                undefinedPermissions.Add(permissionName);
            }
        }

        if (!permissions.Any())
        {
            return new MultiplePermissionWithGrantedProviders(undefinedPermissions.ToArray());
        }
        // 检查权限是否授予
        var result = await GetInternalAsync(
            permissions.ToArray(),
            providerName,
            providerKey
        );

        foreach (var undefinedPermission in undefinedPermissions)
        {
            result.Result.Add(new PermissionWithGrantedProviders(undefinedPermission, false));
        }

        return result;
    }
    protected virtual async Task<MultiplePermissionWithGrantedProviders> GetInternalAsync(
        PermissionDefinition[] permissions,
        string providerName,
        string providerKey)
    {
        var permissionNames = permissions.Select(x => x.Name).ToArray();
        var multiplePermissionWithGrantedProviders = new MultiplePermissionWithGrantedProviders(permissionNames);

        var neededCheckPermissions = new List<PermissionDefinition>();

        foreach (var permission in permissions
                                    .Where(x => x.IsEnabled)
                                    .Where(x => x.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide()))
                                    .Where(x => !x.Providers.Any() || x.Providers.Contains(providerName)))
        {
            if (await SimpleStateCheckerManager.IsEnabledAsync(permission))
            {
                neededCheckPermissions.Add(permission);
            }
        }

        if (!neededCheckPermissions.Any())
        {
            return multiplePermissionWithGrantedProviders;
        }

        // 关键代码 循环调用系统所有权限管理提供程序的 CheckAsync 方法
        foreach (var provider in ManagementProviders)
        {
            permissionNames = neededCheckPermissions.Select(x => x.Name).ToArray();
            var multiplePermissionValueProviderGrantInfo = await provider.CheckAsync(permissionNames, providerName, providerKey);

            // 处理结果
            foreach (var providerResultDict in multiplePermissionValueProviderGrantInfo.Result)
            {
                if (providerResultDict.Value.IsGranted)
                {
                    var permissionWithGrantedProvider = multiplePermissionWithGrantedProviders.Result
                        .First(x => x.Name == providerResultDict.Key);

                    permissionWithGrantedProvider.IsGranted = true;
                    permissionWithGrantedProvider.Providers.Add(new PermissionValueProviderInfo(provider.Name, providerResultDict.Value.ProviderKey));
                }
            }
        }

        return multiplePermissionWithGrantedProviders;
    }

PermissionManagementProvider

用于检查是否拥有权限,设置权限的基类

检查权限源码

    /// <summary>
    /// 检查权限
    /// </summary>
    /// <param name="names">需要检查的权限名</param>
    /// <param name="providerName">权限管理提供名称</param>
    /// <param name="providerKey">需要检查权限的用户ID或用户组ID或其他需要检查权限的ID</param>
    /// <returns></returns>
    public virtual async Task<MultiplePermissionValueProviderGrantInfo> CheckAsync(string[] names, string providerName, string providerKey)
    {
        var multiplePermissionValueProviderGrantInfo = new MultiplePermissionValueProviderGrantInfo(names);
        if (providerName != Name)
        {
            return multiplePermissionValueProviderGrantInfo;
        }
        // 从资源库中获取 providerKey 拥有的权限
        var permissionGrants = await PermissionGrantRepository.GetListAsync(names, providerName, providerKey);

        foreach (var permissionName in names)
        {
            var isGrant = permissionGrants.Any(x => x.Name == permissionName);
            multiplePermissionValueProviderGrantInfo.Result[permissionName] = new PermissionValueProviderGrantInfo(isGrant, providerKey);
        }

        return multiplePermissionValueProviderGrantInfo;
    }

UserPermissionManagementProvider

用户权限管理提供程序,继承PermissionManagementProvider基类

RolePermissionManagementProvider

角色权限管理提供程序,继承PermissionManagementProvider基类,重写了CheckAsync方法

    public override async Task<MultiplePermissionValueProviderGrantInfo> CheckAsync(string[] names, string providerName, string providerKey)
    {
        var multiplePermissionValueProviderGrantInfo = new MultiplePermissionValueProviderGrantInfo(names);
        var permissionGrants = new List<PermissionGrant>();

        // 如果是获取用户角色的权限,则直接从资源库中获取用户角色已授权权限
        if (providerName == Name)
        {
            permissionGrants.AddRange(await PermissionGrantRepository.GetListAsync(names, providerName, providerKey));

        }
        // 如果是获取用户的权限,则获取用户所属用户角色的权限
        if (providerName == UserPermissionValueProvider.ProviderName)
        {
            var userId = Guid.Parse(providerKey);
            var roleNames = await UserRoleFinder.GetRolesAsync(userId);

            foreach (var roleName in roleNames)
            {
                permissionGrants.AddRange(await PermissionGrantRepository.GetListAsync(names, Name, roleName));
            }
        }

        // 以下是处理返回结果
        permissionGrants = permissionGrants.Distinct().ToList();
        if (!permissionGrants.Any())
        {
            return multiplePermissionValueProviderGrantInfo;
        }

        foreach (var permissionName in names)
        {
            var permissionGrant = permissionGrants.FirstOrDefault(x => x.Name == permissionName);
            if (permissionGrant != null)
            {
                multiplePermissionValueProviderGrantInfo.Result[permissionName] = new PermissionValueProviderGrantInfo(true, permissionGrant.ProviderKey);
            }
        }

        return multiplePermissionValueProviderGrantInfo;
    }

当通过 /api/permission-management/permissions?providerName=U&providerKey=XXXX 获取用户权限时,系统通过执行UserPermissionManagementProviderCheckAsync方法获取用户被授予的权限,并通过执行RolePermissionManagementProviderCheckAsync方法获取用户拥有用户角色的权限。

自定义权限规则

添加权限值提供类

Domain层添加CustomPermissionValueProvider.cs继承PermissionValueProvider类,处理权限值的验证

    public class CustomPermissionValueProvider : PermissionValueProvider
    {
        public CustomPermissionValueProvider(IPermissionStore permissionStore) : base(permissionStore)
        {
        }
        public const string ProviderName = "Z";

        public override string Name => ProviderName;

        public override async Task<PermissionGrantResult> CheckAsync(PermissionValueCheckContext context)
        {
            var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value;

            if (userId == null)
            {
                return PermissionGrantResult.Undefined;
            }
            return await PermissionStore.IsGrantedAsync(context.Permission.Name, Name, userId)
                ? PermissionGrantResult.Granted
                : PermissionGrantResult.Undefined;
        }

        public override async Task<MultiplePermissionGrantResult> CheckAsync(PermissionValuesCheckContext context)
        {
            var permissionNames = context.Permissions.Select(x => x.Name).Distinct().ToArray();
            Check.NotNullOrEmpty(permissionNames, nameof(permissionNames));

            var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value;
            if (userId == null)
            {
                return new MultiplePermissionGrantResult(permissionNames);
            }

            return await PermissionStore.IsGrantedAsync(permissionNames, Name, userId);
        }
    }

添加权限管理提供类

Domain层添加CustomPermissionManagementProvider继承PermissionManagementProvider类,并重写CheckAsync方法,定义自己的权限验证方式

    public class CustomPermissionManagementProvider : PermissionManagementProvider
    {
        // 这里的name与CustomPermissionValueProvider中的ProviderName保持一致
        public override string Name => "Z";

        public CustomPermissionManagementProvider(
            IPermissionGrantRepository permissionGrantRepository,
            IGuidGenerator guidGenerator,
            ICurrentTenant currentTenant)
            : base(
                permissionGrantRepository,
                guidGenerator,
                currentTenant)
        {
        }
        public override async Task<PermissionValueProviderGrantInfo> CheckAsync(string name, string providerName, string providerKey)
        {
            var multipleGrantInfo = await CheckAsync(new[] { name }, providerName, providerKey);

            return multipleGrantInfo.Result.Values.First();
        }
        public override async Task<MultiplePermissionValueProviderGrantInfo> CheckAsync(string[] names, string providerName, string providerKey)
        {
            var multiplePermissionValueProviderGrantInfo = new MultiplePermissionValueProviderGrantInfo(names);
            var permissionGrants = new List<PermissionGrant>();
            // 如果是自定义的权限类型获取权限,则从资源库中获取权限
            if (providerName == Name)
            {
                permissionGrants.AddRange(await PermissionGrantRepository.GetListAsync(names, providerName, providerKey));

            }
            // 如果是处理用户的权限,则该提供类赋予用户所有权限
            if (providerName == UserPermissionValueProvider.ProviderName)
            {
                foreach (var name in names) {
                    permissionGrants.Add(new PermissionGrant(GuidGenerator.Create(),name,Name,"测试自定义权限"));
                }
            }

            // 以下处理返回结果
            permissionGrants = permissionGrants.Distinct().ToList();
            if (!permissionGrants.Any())
            {
                return multiplePermissionValueProviderGrantInfo;
            }

            foreach (var permissionName in names)
            {
                var permissionGrant = permissionGrants.FirstOrDefault(x => x.Name == permissionName);
                if (permissionGrant != null)
                {
                    multiplePermissionValueProviderGrantInfo.Result[permissionName] = new PermissionValueProviderGrantInfo(true, permissionGrant.ProviderKey);
                }
            }

            return multiplePermissionValueProviderGrantInfo;
        }
    }

配置自定义权限规则

DomainModuleConfigureServices方法中添加自定义的权限规则配置

            Configure<AbpPermissionOptions>(options =>
            {
                options.ValueProviders.Add<CustomPermissionValueProvider>();
            });

            Configure<PermissionManagementOptions>(options =>
            {
                options.ManagementProviders.Add<CustomPermissionManagementProvider>();
                options.ProviderPolicies.Add(CustomPermissionValueProvider.ProviderName, "AbpIdentity.Users.ManagePermissions");
            });

如此完成自定义权限规则

Api返回JSON

{
	"entityDisplayName": "62a4b9b6-161e-6b1f-ccbe-3a0aa43a2249",
	"groups": [{
		"name": "AbpIdentity",
		"displayName": "身份标识管理",
		"permissions": [{
			"name": "AbpIdentity.Roles",
			"displayName": "角色管理",
			"parentName": null,
			"isGranted": true,
			"allowedProviders": [],
			"grantedProviders": [{
				"providerName": "R",
				"providerKey": "admin"
			}, {
				"providerName": "Z",
				"providerKey": "测试自定义权限"
			}]
		}, {
			"name": "AbpIdentity.Roles.Create",
			"displayName": "创建",
			"parentName": "AbpIdentity.Roles",
			"isGranted": true,
			"allowedProviders": [],
			"grantedProviders": [{
				"providerName": "R",
				"providerKey": "admin"
			}, {
				"providerName": "Z",
				"providerKey": "测试自定义权限"
			}]
		},
        ...]
	}, {
		"name": "PurchaseManage",
		"displayName": "采购管理",
		"permissions": [{
			"name": "PurchaseManage.PruchaseOrder",
			"displayName": "采购订单",
			"parentName": null,
			"isGranted": true,
			"allowedProviders": [],
			"grantedProviders": [{
				"providerName": "U",
				"providerKey": "62a4b9b6-161e-6b1f-ccbe-3a0aa43a2249"
			}, {
				"providerName": "Z",
				"providerKey": "测试自定义权限"
			}]
		},
        ...]
	}]
}

页面效果

img

posted @ 2023-05-24 10:20  $("#阿飞")  阅读(282)  评论(0编辑  收藏  举报