25 changed files with 286 additions and 287 deletions
@ -0,0 +1,19 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Volo.Abp.Uow" Version="3.2.0" /> |
||||
|
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" Version="3.2.0" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\permissions-management\LINGYUN.Abp.PermissionManagement.Domain\LINGYUN.Abp.PermissionManagement.Domain.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace LINGYUN.Abp.PermissionManagement.Identity |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpPermissionManagementDomainModule), |
||||
|
typeof(Volo.Abp.PermissionManagement.Identity.AbpPermissionManagementDomainIdentityModule) |
||||
|
)] |
||||
|
public class AbpPermissionManagementDomainIdentityModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.Identity; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
using Volo.Abp.Threading; |
||||
|
using Volo.Abp.Uow; |
||||
|
|
||||
|
namespace LINGYUN.Abp.PermissionManagement.Identity |
||||
|
{ |
||||
|
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] |
||||
|
[ExposeServices(typeof(IPermissionManager), typeof(PermissionManager), typeof(DefaultPermissionManager))] |
||||
|
public class IdentityPermissionManager : DefaultPermissionManager |
||||
|
{ |
||||
|
protected IUnitOfWorkManager UnitOfWorkManager => LazyGetRequiredService(ref _unitOfWorkManager); |
||||
|
private IUnitOfWorkManager _unitOfWorkManager; |
||||
|
|
||||
|
protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; |
||||
|
|
||||
|
protected IUserRoleFinder UserRoleFinder { get; } |
||||
|
public IdentityPermissionManager( |
||||
|
IPermissionDefinitionManager permissionDefinitionManager, |
||||
|
IPermissionGrantRepository permissionGrantRepository, |
||||
|
IPermissionStore permissionStore, |
||||
|
IServiceProvider serviceProvider, |
||||
|
IGuidGenerator guidGenerator, |
||||
|
IOptions<PermissionManagementOptions> options, |
||||
|
ICurrentTenant currentTenant, |
||||
|
IUserRoleFinder userRoleFinder) |
||||
|
: base(permissionDefinitionManager, permissionGrantRepository, permissionStore, serviceProvider, guidGenerator, options, currentTenant) |
||||
|
{ |
||||
|
UserRoleFinder = userRoleFinder; |
||||
|
} |
||||
|
|
||||
|
protected override async Task<bool> IsGrantedAsync(string permissionName, string providerName, string providerKey) |
||||
|
{ |
||||
|
if (!RolePermissionValueProvider.ProviderName.Equals(providerName)) |
||||
|
{ |
||||
|
// 如果查询的是用户权限,需要查询用户角色权限
|
||||
|
if (providerName == UserPermissionValueProvider.ProviderName) |
||||
|
{ |
||||
|
var userId = Guid.Parse(providerKey); |
||||
|
var roleNames = await GetUserRolesAsync(userId); |
||||
|
foreach (var roleName in roleNames) |
||||
|
{ |
||||
|
var permissionGrant = await PermissionStore.IsGrantedAsync(permissionName, RolePermissionValueProvider.ProviderName, roleName); |
||||
|
if (permissionGrant) |
||||
|
{ |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return await base.IsGrantedAsync(permissionName, providerName, providerKey); |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<string[]> GetUserRolesAsync(Guid userId) |
||||
|
{ |
||||
|
// 通过工作单元来缓存用户角色,防止多次查询
|
||||
|
if (CurrentUnitOfWork != null) |
||||
|
{ |
||||
|
var userRoleItemKey = $"FindRolesByUser:{userId}"; |
||||
|
|
||||
|
return CurrentUnitOfWork.GetOrAddItem(userRoleItemKey, (key) => |
||||
|
{ |
||||
|
var roles = AsyncHelper.RunSync(async ()=> await UserRoleFinder.GetRolesAsync(userId)); |
||||
|
return roles; |
||||
|
}); |
||||
|
} |
||||
|
return await UserRoleFinder.GetRolesAsync(userId); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
# LINGYUN.Abp.PermissionManagement.Domain.Identity |
||||
|
|
||||
|
重写 **LINGYUN.Abp.PermissionManagement.Domain** |
||||
|
|
||||
|
当查询用户权限时,先获取用户角色组权限 |
||||
|
|
||||
|
#### 注意 |
||||
|
|
||||
|
此模块已经引用 **Volo.Abp.PermissionManagement.Identity.AbpPermissionManagementDomainIdentityModule** 无需再次引用 |
||||
|
|
||||
|
## 配置使用 |
||||
|
|
||||
|
|
||||
|
```csharp |
||||
|
[DependsOn(typeof(LINGYUN.Abp.PermissionManagement.Identity.AbpPermissionManagementDomainIdentityModule))] |
||||
|
public class YouProjectModule : AbpModule |
||||
|
{ |
||||
|
// other |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace LINGYUN.Abp.PermissionManagement |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(Volo.Abp.PermissionManagement.AbpPermissionManagementDomainModule))] |
||||
|
public class AbpPermissionManagementDomainModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.PermissionManagement; |
||||
|
|
||||
|
namespace LINGYUN.Abp.PermissionManagement |
||||
|
{ |
||||
|
[Dependency(ServiceLifetime.Singleton, ReplaceServices = true)] |
||||
|
[ExposeServices(typeof(IPermissionManager), typeof(PermissionManager))] |
||||
|
public class DefaultPermissionManager : PermissionManager |
||||
|
{ |
||||
|
#region DependencyInjection
|
||||
|
|
||||
|
protected readonly object ServiceProviderLock = new object(); |
||||
|
|
||||
|
protected TService LazyGetRequiredService<TService>(ref TService reference) |
||||
|
=> LazyGetRequiredService(typeof(TService), ref reference); |
||||
|
|
||||
|
protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference) |
||||
|
{ |
||||
|
if (reference == null) |
||||
|
{ |
||||
|
lock (ServiceProviderLock) |
||||
|
{ |
||||
|
if (reference == null) |
||||
|
{ |
||||
|
reference = (TRef)ServiceProvider.GetRequiredService(serviceType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return reference; |
||||
|
} |
||||
|
protected IServiceProvider ServiceProvider { get; } |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
protected IPermissionStore PermissionStore { get; } |
||||
|
public DefaultPermissionManager( |
||||
|
IPermissionDefinitionManager permissionDefinitionManager, |
||||
|
IPermissionGrantRepository permissionGrantRepository, |
||||
|
IPermissionStore permissionStore, |
||||
|
IServiceProvider serviceProvider, |
||||
|
IGuidGenerator guidGenerator, |
||||
|
IOptions<PermissionManagementOptions> options, |
||||
|
ICurrentTenant currentTenant) |
||||
|
: base(permissionDefinitionManager, permissionGrantRepository, serviceProvider, guidGenerator, options, currentTenant) |
||||
|
{ |
||||
|
ServiceProvider = serviceProvider; |
||||
|
PermissionStore = permissionStore; |
||||
|
} |
||||
|
|
||||
|
public override async Task SetAsync(string permissionName, string providerName, string providerKey, bool isGranted) |
||||
|
{ |
||||
|
await base.SetAsync(permissionName, providerName, providerKey, isGranted); |
||||
|
|
||||
|
// 不需要改缓存,因为权限实体变更会自动清理缓存
|
||||
|
//var cacheKey = PermissionGrantCacheItem.CalculateCacheKey(permissionName, providerName, providerKey);
|
||||
|
//var cacheItem = new PermissionGrantCacheItem(isGranted);
|
||||
|
//await PermissionGrantChche.SetAsync(cacheKey, cacheItem);
|
||||
|
} |
||||
|
|
||||
|
protected override async Task<PermissionWithGrantedProviders> GetInternalAsync(PermissionDefinition permission, string providerName, string providerKey) |
||||
|
{ |
||||
|
var result = new PermissionWithGrantedProviders(permission.Name, false); |
||||
|
|
||||
|
if (!permission.IsEnabled) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
if (!permission.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide())) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
if (permission.Providers.Any() && !permission.Providers.Contains(providerName)) |
||||
|
{ |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
// 这么做的坏处就是没法给特定的Provider设定是否授权字段
|
||||
|
// result.Providers 会出现假数据 UserPermissionProvider未授权, 而所属的
|
||||
|
|
||||
|
result.IsGranted = await IsGrantedAsync(permission.Name, providerName, providerKey); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
protected virtual async Task<bool> IsGrantedAsync(string permissionName, string providerName, string providerKey) |
||||
|
{ |
||||
|
return await PermissionStore.IsGrantedAsync(permissionName, providerName, providerKey); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
# LINGYUN.Abp.PermissionManagement.Domain |
||||
|
|
||||
|
重写 **Volo.Abp.PermissionManagement.PermissionManager**, 在查询权限的时候优先检查缓存 |
||||
|
|
||||
|
大部分重写的模块都和官方模块名称保持一致,通过命名空间区分,主要是只改写了一小部分或者增加额外的功能 |
||||
|
如果大部分模块代码都重写,或者完全就是扩展模块,才会定义自己的名字 |
||||
|
|
||||
|
#### 注意 |
||||
|
|
||||
|
当使用了此模块,可能会出现您不愿意见到的场景,因为当您只需要查看某个实体拥有的权限,然后却为此建立了它的全部缓存项 |
||||
|
|
||||
|
在一些特定场景下(**比如云缓存**),请避免引用此模块,以免产生额外的费用 |
||||
|
|
||||
|
## 配置使用 |
||||
|
|
||||
|
|
||||
|
```csharp |
||||
|
[DependsOn(typeof(LINGYUN.Abp.PermissionManagement.AbpPermissionManagementDomainModule))] |
||||
|
public class YouProjectModule : AbpModule |
||||
|
{ |
||||
|
// other |
||||
|
} |
||||
@ -1,17 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>netstandard2.0</TargetFramework> |
|
||||
<RootNamespace></RootNamespace> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Volo.Abp.Ddd.Application" Version="3.0.0" /> |
|
||||
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Shared" Version="3.0.0" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<Folder Include="LINGYUN\Abp\PermissionManagement\Localization\" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,7 +0,0 @@ |
|||||
bin |
|
||||
obj |
|
||||
Logs |
|
||||
appsettings.*.json |
|
||||
node_modules |
|
||||
yarn.lock |
|
||||
package-lock.json |
|
||||
@ -1,13 +0,0 @@ |
|||||
<Project Sdk="Microsoft.NET.Sdk"> |
|
||||
|
|
||||
<PropertyGroup> |
|
||||
<TargetFramework>netstandard2.0</TargetFramework> |
|
||||
<RootNamespace /> |
|
||||
</PropertyGroup> |
|
||||
|
|
||||
<ItemGroup> |
|
||||
<PackageReference Include="Volo.Abp.PermissionManagement.Domain" Version="3.0.0" /> |
|
||||
<PackageReference Include="Volo.Abp.PermissionManagement.Application.Contracts" Version="3.0.0" /> |
|
||||
</ItemGroup> |
|
||||
|
|
||||
</Project> |
|
||||
@ -1,13 +0,0 @@ |
|||||
using Volo.Abp.Modularity; |
|
||||
using Volo.Abp.PermissionManagement; |
|
||||
|
|
||||
namespace LINGYUN.Abp.PermissionManagement |
|
||||
{ |
|
||||
[DependsOn( |
|
||||
typeof(AbpPermissionManagementDomainModule), |
|
||||
typeof(AbpPermissionManagementApplicationContractsModule) |
|
||||
)] |
|
||||
public class AbpPermissionManagementApplicationModule : AbpModule |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,156 +0,0 @@ |
|||||
using Microsoft.AspNetCore.Authorization; |
|
||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using Microsoft.Extensions.Options; |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp; |
|
||||
using Volo.Abp.Application.Services; |
|
||||
using Volo.Abp.Authorization.Permissions; |
|
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.Clients; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
using Volo.Abp.PermissionManagement; |
|
||||
using Volo.Abp.Users; |
|
||||
|
|
||||
namespace LINGYUN.Abp.PermissionManagement |
|
||||
{ |
|
||||
[Authorize] |
|
||||
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] |
|
||||
[ExposeServices(typeof(IPermissionAppService), typeof(PermissionAppService))] |
|
||||
public class PermissionAppService : ApplicationService, IPermissionAppService |
|
||||
{ |
|
||||
protected PermissionManagementOptions Options { get; } |
|
||||
protected IDistributedCache<PermissionGrantCacheItem> Cache { get; } |
|
||||
protected IPermissionGrantRepository PermissionGrantRepository { get; } |
|
||||
protected IPermissionDefinitionManager PermissionDefinitionManager { get; } |
|
||||
public PermissionAppService( |
|
||||
IDistributedCache<PermissionGrantCacheItem> cache, |
|
||||
IPermissionGrantRepository permissionGrantRepository, |
|
||||
IPermissionDefinitionManager permissionDefinitionManager, |
|
||||
IOptions<PermissionManagementOptions> options) |
|
||||
{ |
|
||||
Cache = cache; |
|
||||
Options = options.Value; |
|
||||
PermissionGrantRepository = permissionGrantRepository; |
|
||||
PermissionDefinitionManager = permissionDefinitionManager; |
|
||||
} |
|
||||
public virtual async Task<GetPermissionListResultDto> GetAsync(string providerName, string providerKey) |
|
||||
{ |
|
||||
var permissionListResult = new GetPermissionListResultDto |
|
||||
{ |
|
||||
EntityDisplayName = providerKey, |
|
||||
Groups = new List<PermissionGroupDto>() |
|
||||
}; |
|
||||
var multiTenancySide = CurrentTenant.GetMultiTenancySide(); |
|
||||
var permissionGroups = PermissionDefinitionManager.GetGroups(); |
|
||||
IEnumerable<PermissionGrant> permissions = |
|
||||
await PermissionGrantRepository.GetListAsync(providerName, providerKey); |
|
||||
foreach (var permissionGroup in permissionGroups) |
|
||||
{ |
|
||||
var groupDto = new PermissionGroupDto |
|
||||
{ |
|
||||
Name = permissionGroup.Name, |
|
||||
DisplayName = permissionGroup.DisplayName.Localize(StringLocalizerFactory), |
|
||||
Permissions = new List<PermissionGrantInfoDto>() |
|
||||
}; |
|
||||
foreach (var permission in permissionGroup.GetPermissionsWithChildren()) |
|
||||
{ |
|
||||
if (!permission.IsEnabled) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
if (permission.Providers.Any() && !permission.Providers.Contains(providerName)) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
if (!permission.MultiTenancySide.HasFlag(multiTenancySide)) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
var grantInfoDto = new PermissionGrantInfoDto |
|
||||
{ |
|
||||
Name = permission.Name, |
|
||||
DisplayName = permission.DisplayName.Localize(StringLocalizerFactory), |
|
||||
ParentName = permission.Parent?.Name, |
|
||||
AllowedProviders = permission.Providers, |
|
||||
GrantedProviders = new List<ProviderInfoDto>() |
|
||||
}; |
|
||||
|
|
||||
var grantedPermissions = permissions.Where(p => p.Name.Equals(permission.Name)); |
|
||||
|
|
||||
foreach (var grantedPermission in grantedPermissions) |
|
||||
{ |
|
||||
grantInfoDto.IsGranted = true; |
|
||||
grantInfoDto.GrantedProviders.Add(new ProviderInfoDto |
|
||||
{ |
|
||||
ProviderKey = grantedPermission.ProviderKey, |
|
||||
ProviderName = grantedPermission.ProviderName |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
groupDto.Permissions.Add(grantInfoDto); |
|
||||
} |
|
||||
|
|
||||
if (groupDto.Permissions.Any()) |
|
||||
{ |
|
||||
permissionListResult.Groups.Add(groupDto); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return permissionListResult; |
|
||||
} |
|
||||
|
|
||||
public virtual async Task UpdateAsync(string providerName, string providerKey, UpdatePermissionsDto input) |
|
||||
{ |
|
||||
await CheckProviderPolicy(providerName); |
|
||||
|
|
||||
var permissions = await PermissionGrantRepository.GetListAsync(providerName, providerKey); |
|
||||
foreach(var permission in input.Permissions) |
|
||||
{ |
|
||||
var editPermission = permissions.FirstOrDefault(p => p.Name.Equals(permission.Name)); |
|
||||
if(editPermission == null) |
|
||||
{ |
|
||||
if(permission.IsGranted) |
|
||||
{ |
|
||||
var permissionGrant = new PermissionGrant(GuidGenerator.Create(), |
|
||||
permission.Name, providerName, providerKey, CurrentTenant.Id); |
|
||||
await PermissionGrantRepository.InsertAsync(permissionGrant); |
|
||||
} |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
if (!permission.IsGranted) |
|
||||
{ |
|
||||
await PermissionGrantRepository.DeleteAsync(editPermission.Id); |
|
||||
} |
|
||||
} |
|
||||
// 同步变更缓存里的权限配置
|
|
||||
var cacheKey = CalculateCacheKey(permission.Name, providerName, providerKey); |
|
||||
var cacheItem = new PermissionGrantCacheItem(permission.IsGranted); |
|
||||
await Cache.SetAsync(cacheKey, cacheItem); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
protected virtual async Task CheckProviderPolicy(string providerName) |
|
||||
{ |
|
||||
var policyName = Options.ProviderPolicies.GetOrDefault(providerName); |
|
||||
if (policyName.IsNullOrEmpty()) |
|
||||
{ |
|
||||
throw new AbpException($"No policy defined to get/set permissions for the provider '{policyName}'. Use {nameof(PermissionManagementOptions)} to map the policy."); |
|
||||
} |
|
||||
|
|
||||
await AuthorizationService.CheckAsync(policyName); |
|
||||
} |
|
||||
|
|
||||
protected virtual string CalculateCacheKey(string name, string providerName, string providerKey) |
|
||||
{ |
|
||||
return PermissionGrantCacheItem.CalculateCacheKey(name, providerName, providerKey); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,7 +0,0 @@ |
|||||
bin |
|
||||
obj |
|
||||
Logs |
|
||||
appsettings.*.json |
|
||||
node_modules |
|
||||
yarn.lock |
|
||||
package-lock.json |
|
||||
@ -1,8 +0,0 @@ |
|||||
using System; |
|
||||
|
|
||||
namespace LINGYUN.Abp.PermissionManagement |
|
||||
{ |
|
||||
public class Class1 |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Text; |
|
||||
using Volo.Abp.Guids; |
|
||||
using Volo.Abp.MultiTenancy; |
|
||||
using Volo.Abp.PermissionManagement; |
|
||||
|
|
||||
namespace LINGYUN.Abp.PermissionManagement |
|
||||
{ |
|
||||
public abstract class PermissionManagementProvider : IPermissionManagementProvider |
|
||||
{ |
|
||||
public abstract string Name { get; } |
|
||||
|
|
||||
protected IPermissionGrantRepository PermissionGrantRepository { get; } |
|
||||
|
|
||||
protected IGuidGenerator GuidGenerator { get; } |
|
||||
|
|
||||
protected ICurrentTenant CurrentTenant { get; } |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue