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 |
|||
} |
|||
@ -1,12 +1,14 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.Domain" Version="2.7.0" /> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.Domain" Version="3.2.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -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