Resolved #728: Allow to set client based permissions like roles/users

pull/786/head^2
Halil ibrahim Kalkan 7 years ago
parent a874171a59
commit 4913cbc158

@ -1,6 +1,7 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Clients;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Users;
@ -10,11 +11,16 @@ namespace Volo.Abp.Authorization
{
private readonly IAuthorizationService _authorizationService;
private readonly ICurrentUser _currentUser;
private readonly ICurrentClient _currentClient;
public MethodInvocationAuthorizationService(IAuthorizationService authorizationService, ICurrentUser currentUser)
public MethodInvocationAuthorizationService(
IAuthorizationService authorizationService,
ICurrentUser currentUser,
ICurrentClient currentClient)
{
_authorizationService = authorizationService;
_currentUser = currentUser;
_currentClient = currentClient;
}
public async Task CheckAsync(MethodInvocationAuthorizationContext context)
@ -53,7 +59,8 @@ namespace Volo.Abp.Authorization
{
if (authorizationAttribute.Policy == null)
{
if (!_currentUser.IsAuthenticated) //TODO: What about API calls without user id?
//TODO: Can we find a better, unified, way of checking if current request has been authenticated
if (!_currentUser.IsAuthenticated && !_currentClient.IsAuthenticated)
{
throw new AbpAuthorizationException("Authorization failed! User has not logged in.");
}

@ -0,0 +1,35 @@
using System.Threading.Tasks;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Authorization.Permissions
{
public class ClientPermissionValueProvider : PermissionValueProvider
{
public const string ProviderName = "Client";
public override string Name => ProviderName;
public ClientPermissionValueProvider(IPermissionStore permissionStore)
: base(permissionStore)
{
}
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionValueCheckContext context)
{
var clientId = context.Principal?.FindFirst(AbpClaimTypes.ClientId)?.Value;
if (clientId == null)
{
return PermissionValueProviderGrantInfo.NonGranted;
}
if (await PermissionStore.IsGrantedAsync(context.Permission.Name, Name, clientId))
{
return new PermissionValueProviderGrantInfo(true, clientId);
}
return PermissionValueProviderGrantInfo.NonGranted;
}
}
}

@ -21,6 +21,21 @@ namespace System.Security.Principal
return Guid.Parse(userIdOrNull.Value);
}
public static Guid? FindUserId([NotNull] this IIdentity identity)
{
Check.NotNull(identity, nameof(identity));
var claimsIdentity = identity as ClaimsIdentity;
var userIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.UserId);
if (userIdOrNull == null || userIdOrNull.Value.IsNullOrWhiteSpace())
{
return null;
}
return Guid.Parse(userIdOrNull.Value);
}
public static Guid? FindTenantId([NotNull] this ClaimsPrincipal principal)
{
Check.NotNull(principal, nameof(principal));
@ -34,34 +49,47 @@ namespace System.Security.Principal
return Guid.Parse(tenantIdOrNull.Value);
}
public static Guid? FindUserId([NotNull] this IIdentity identity)
public static Guid? FindTenantId([NotNull] this IIdentity identity)
{
Check.NotNull(identity, nameof(identity));
var claimsIdentity = identity as ClaimsIdentity;
var userIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.UserId);
if (userIdOrNull == null || userIdOrNull.Value.IsNullOrWhiteSpace())
var tenantIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.TenantId);
if (tenantIdOrNull == null || tenantIdOrNull.Value.IsNullOrWhiteSpace())
{
return null;
}
return Guid.Parse(userIdOrNull.Value);
return Guid.Parse(tenantIdOrNull.Value);
}
public static Guid? FindTenantId([NotNull] this IIdentity identity)
public static string FindClientId([NotNull] this ClaimsPrincipal principal)
{
Check.NotNull(principal, nameof(principal));
var clientIdOrNull = principal.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.ClientId);
if (clientIdOrNull == null || clientIdOrNull.Value.IsNullOrWhiteSpace())
{
return null;
}
return clientIdOrNull.Value;
}
public static string FindClientId([NotNull] this IIdentity identity)
{
Check.NotNull(identity, nameof(identity));
var claimsIdentity = identity as ClaimsIdentity;
var tenantIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.TenantId);
if (tenantIdOrNull == null || tenantIdOrNull.Value.IsNullOrWhiteSpace())
var clientIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.ClientId);
if (clientIdOrNull == null || clientIdOrNull.Value.IsNullOrWhiteSpace())
{
return null;
}
return Guid.Parse(tenantIdOrNull.Value);
return clientIdOrNull.Value;
}
}
}

@ -0,0 +1,20 @@
using System.Security.Principal;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Clients
{
public class CurrentClient : ICurrentClient, ITransientDependency
{
public virtual string Id => _principalAccessor.Principal?.FindClientId();
public virtual bool IsAuthenticated => Id != null;
private readonly ICurrentPrincipalAccessor _principalAccessor;
public CurrentClient(ICurrentPrincipalAccessor principalAccessor)
{
_principalAccessor = principalAccessor;
}
}
}

@ -0,0 +1,9 @@
namespace Volo.Abp.Clients
{
public interface ICurrentClient
{
string Id { get; }
bool IsAuthenticated { get; }
}
}

@ -47,5 +47,10 @@ namespace Volo.Abp.Security.Claims
/// Default: "phone_number_verified".
/// </summary>
public static string TenantId { get; set; } = "tenantid";
/// <summary>
/// Default: "client_id".
/// </summary>
public static string ClientId { get; set; } = "client_id";
}
}

@ -36,7 +36,7 @@ namespace Volo.Abp.PermissionManagement.Identity
);
}
if (providerName == "User")
if (providerName == UserPermissionValueProvider.ProviderName)
{
var userId = Guid.Parse(providerKey);
var roleNames = await _userRoleFinder.GetRolesAsync(userId);

@ -8,8 +8,8 @@ namespace Volo.Abp.PermissionManagement.Identity
{
public override string Name => UserPermissionValueProvider.ProviderName;
public UserPermissionManagementProvider(IPermissionGrantRepository
permissionGrantRepository,
public UserPermissionManagementProvider(
IPermissionGrantRepository permissionGrantRepository,
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant)
: base(

@ -21,7 +21,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.IdentityServer.Tes
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.IdentityServer.MongoDB.Tests", "test\Volo.Abp.IdentityServer.MongoDB.Tests\Volo.Abp.IdentityServer.MongoDB.Tests.csproj", "{2E18B471-7FCA-497B-90FF-6AA9172CC62F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.IdentityServer.Domain.Tests", "test\Volo.Abp.IdentityServer.Domain.Tests\Volo.Abp.IdentityServer.Domain.Tests.csproj", "{0680D0B6-51C0-4812-8A0B-192FDE717E60}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.IdentityServer.Domain.Tests", "test\Volo.Abp.IdentityServer.Domain.Tests\Volo.Abp.IdentityServer.Domain.Tests.csproj", "{0680D0B6-51C0-4812-8A0B-192FDE717E60}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.PermissionManagement.Domain.IdentityServer", "src\Volo.Abp.PermissionManagement.Domain.IdentityServer\Volo.Abp.PermissionManagement.Domain.IdentityServer.csproj", "{072BD630-FB89-45FC-BA2D-12A9745AAB93}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -61,6 +63,10 @@ Global
{0680D0B6-51C0-4812-8A0B-192FDE717E60}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0680D0B6-51C0-4812-8A0B-192FDE717E60}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0680D0B6-51C0-4812-8A0B-192FDE717E60}.Release|Any CPU.Build.0 = Release|Any CPU
{072BD630-FB89-45FC-BA2D-12A9745AAB93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{072BD630-FB89-45FC-BA2D-12A9745AAB93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{072BD630-FB89-45FC-BA2D-12A9745AAB93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{072BD630-FB89-45FC-BA2D-12A9745AAB93}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -74,6 +80,7 @@ Global
{9CD1BFDB-DD76-4194-ACAD-A64541AC2069} = {2C792EC1-BA27-44ED-B7CC-D0939553F1B2}
{2E18B471-7FCA-497B-90FF-6AA9172CC62F} = {2C792EC1-BA27-44ED-B7CC-D0939553F1B2}
{0680D0B6-51C0-4812-8A0B-192FDE717E60} = {2C792EC1-BA27-44ED-B7CC-D0939553F1B2}
{072BD630-FB89-45FC-BA2D-12A9745AAB93} = {59A0FC0F-EA6D-477B-84A7-3B1E41B4C858}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {45562023-C330-4060-A583-2BA10F472D3D}

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Volo.Abp.PermissionManagement.Domain.IdentityServer</AssemblyName>
<PackageId>Volo.Abp.PermissionManagement.Domain.IdentityServer</PackageId>
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.IdentityServer.Domain.Shared\Volo.Abp.IdentityServer.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\permission-management\src\Volo.Abp.PermissionManagement.Domain\Volo.Abp.PermissionManagement.Domain.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,18 @@
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Modularity;
namespace Volo.Abp.PermissionManagement.IdentityServer
{
public class AbpPermissionManagementDomainIdentityServerModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<PermissionManagementOptions>(options =>
{
options.ManagementProviders.Add<ClientPermissionManagementProvider>();
options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = "IdentityServer.Client.ManagePermissions";
});
}
}
}

@ -0,0 +1,23 @@
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.PermissionManagement.IdentityServer
{
public class ClientPermissionManagementProvider : PermissionManagementProvider
{
public override string Name => ClientPermissionValueProvider.ProviderName;
public ClientPermissionManagementProvider(
IPermissionGrantRepository permissionGrantRepository,
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant)
: base(
permissionGrantRepository,
guidGenerator,
currentTenant)
{
}
}
}

@ -140,6 +140,7 @@ $projects = (
# modules/identityserver
"modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared",
"modules/identityserver/src/Volo.Abp.IdentityServer.Domain",
"modules/identityserver/src/Volo.Abp.PermissionManagement.Domain.IdentityServer",
"modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore",
"modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB",

@ -27,6 +27,7 @@
<ProjectReference Include="..\..\..\..\modules\identity\src\Volo.Abp.Identity.HttpApi\Volo.Abp.Identity.HttpApi.csproj" />
<ProjectReference Include="..\..\..\..\modules\identity\src\Volo.Abp.Identity.HttpApi.Client\Volo.Abp.Identity.HttpApi.Client.csproj" />
<ProjectReference Include="..\..\..\..\modules\identity\src\Volo.Abp.PermissionManagement.Domain.Identity\Volo.Abp.PermissionManagement.Domain.Identity.csproj" />
<ProjectReference Include="..\..\..\..\modules\identityserver\src\Volo.Abp.PermissionManagement.Domain.IdentityServer\Volo.Abp.PermissionManagement.Domain.IdentityServer.csproj" />
<ProjectReference Include="..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.Application\Volo.Abp.PermissionManagement.Application.csproj" />
<ProjectReference Include="..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.HttpApi\Volo.Abp.PermissionManagement.HttpApi.csproj" />
<ProjectReference Include="..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" />

@ -14,6 +14,7 @@ using Volo.Abp.PermissionManagement;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.HttpApi;
using Volo.Abp.PermissionManagement.Identity;
using Volo.Abp.PermissionManagement.IdentityServer;
using Volo.Abp.Security.Claims;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Blogging;
@ -31,7 +32,8 @@ namespace BackendAdminAppGateway.Host
typeof(AbpPermissionManagementHttpApiModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(BloggingApplicationContractsModule),
typeof(AbpPermissionManagementDomainIdentityModule)
typeof(AbpPermissionManagementDomainIdentityModule),
typeof(AbpPermissionManagementDomainIdentityServerModule)
)]
public class BackendAdminAppGatewayHostModule : AbpModule
{

Loading…
Cancel
Save