Browse Source

Merge pull request #2659 from mperk/#214-authorization-improvements

#214 authorization improvements
pull/3559/merge
Halil İbrahim Kalkan 7 years ago
committed by GitHub
parent
commit
63cb2f0c8d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 45
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs
  2. 25
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AuthorizationTestBase.cs
  3. 28
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs
  4. 1
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs
  5. 13
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedServiceWithRole.cs
  6. 2
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs
  7. 27
      framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedServiceWithRole.cs

45
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/MethodInvocationAuthorizationService.cs

@ -3,26 +3,21 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Clients;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Users;
namespace Volo.Abp.Authorization namespace Volo.Abp.Authorization
{ {
public class MethodInvocationAuthorizationService : IMethodInvocationAuthorizationService, ITransientDependency public class MethodInvocationAuthorizationService : IMethodInvocationAuthorizationService, ITransientDependency
{ {
private readonly IAuthorizationService _authorizationService; private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider;
private readonly ICurrentUser _currentUser; private readonly IAbpAuthorizationService _abpAuthorizationService;
private readonly ICurrentClient _currentClient;
public MethodInvocationAuthorizationService( public MethodInvocationAuthorizationService(
IAuthorizationService authorizationService, IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider,
ICurrentUser currentUser, IAbpAuthorizationService abpAuthorizationService)
ICurrentClient currentClient)
{ {
_authorizationService = authorizationService; _abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider;
_currentUser = currentUser; _abpAuthorizationService = abpAuthorizationService;
_currentClient = currentClient;
} }
public async Task CheckAsync(MethodInvocationAuthorizationContext context) public async Task CheckAsync(MethodInvocationAuthorizationContext context)
@ -32,10 +27,14 @@ namespace Volo.Abp.Authorization
return; return;
} }
foreach (var authorizationAttribute in GetAuthorizationDataAttributes(context.Method)) var authorizationPolicy = await AuthorizationPolicy.CombineAsync(_abpAuthorizationPolicyProvider,
GetAuthorizationDataAttributes(context.Method));
if (authorizationPolicy == null)
{ {
await CheckAsync(authorizationAttribute); return;
} }
await _abpAuthorizationService.CheckAsync(authorizationPolicy);
} }
protected virtual bool AllowAnonymous(MethodInvocationAuthorizationContext context) protected virtual bool AllowAnonymous(MethodInvocationAuthorizationContext context)
@ -49,7 +48,7 @@ namespace Volo.Abp.Authorization
.GetCustomAttributes(true) .GetCustomAttributes(true)
.OfType<IAuthorizeData>(); .OfType<IAuthorizeData>();
if (methodInfo.IsPublic) if (methodInfo.IsPublic && methodInfo.DeclaringType != null)
{ {
attributes = attributes attributes = attributes
.Union( .Union(
@ -61,23 +60,5 @@ namespace Volo.Abp.Authorization
return attributes; return attributes;
} }
protected async Task CheckAsync(IAuthorizeData authorizationAttribute)
{
if (authorizationAttribute.Policy == null)
{
//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.");
}
}
else
{
await _authorizationService.CheckAsync(authorizationAttribute.Policy);
}
//TODO: What about roles and other props?
}
} }
} }

25
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AuthorizationTestBase.cs

@ -1,4 +1,10 @@
using Volo.Abp.Testing; using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading;
using Volo.Abp.Security.Claims;
using Volo.Abp.Testing;
namespace Volo.Abp.Authorization namespace Volo.Abp.Authorization
{ {
@ -8,5 +14,20 @@ namespace Volo.Abp.Authorization
{ {
options.UseAutofac(); options.UseAutofac();
} }
protected override void AfterAddApplication(IServiceCollection services)
{
var claims = new List<Claim>() {
new Claim(AbpClaimTypes.UserName, "Douglas"),
new Claim(AbpClaimTypes.UserId, "1fcf46b2-28c3-48d0-8bac-fa53268a2775"),
new Claim(AbpClaimTypes.Role, "MyRole")
};
var identity = new ClaimsIdentity(claims);
var claimsPrincipal = new ClaimsPrincipal(identity);
var principalAccessor = Substitute.For<ICurrentPrincipalAccessor>();
principalAccessor.Principal.Returns(ci => claimsPrincipal);
Thread.CurrentPrincipal = claimsPrincipal;
}
} }
} }

28
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/Authorization_Tests.cs

@ -9,11 +9,13 @@ namespace Volo.Abp.Authorization
public class Authorization_Tests : AuthorizationTestBase public class Authorization_Tests : AuthorizationTestBase
{ {
private readonly IMyAuthorizedService1 _myAuthorizedService1; private readonly IMyAuthorizedService1 _myAuthorizedService1;
private readonly IMyAuthorizedServiceWithRole _myAuthorizedServiceWithRole;
private readonly IPermissionDefinitionManager _permissionDefinitionManager; private readonly IPermissionDefinitionManager _permissionDefinitionManager;
public Authorization_Tests() public Authorization_Tests()
{ {
_myAuthorizedService1 = GetRequiredService<IMyAuthorizedService1>(); _myAuthorizedService1 = GetRequiredService<IMyAuthorizedService1>();
_myAuthorizedServiceWithRole = GetRequiredService<IMyAuthorizedServiceWithRole>();
_permissionDefinitionManager = GetRequiredService<IPermissionDefinitionManager>(); _permissionDefinitionManager = GetRequiredService<IPermissionDefinitionManager>();
} }
@ -52,5 +54,31 @@ namespace Volo.Abp.Authorization
{ {
_permissionDefinitionManager.GetGroups().Count.ShouldBe(1); _permissionDefinitionManager.GetGroups().Count.ShouldBe(1);
} }
[Fact]
public async Task Should_Not_Allow_To_Call_Method_If_Has_No_Role_ProtectedByRole_Async()
{
await Assert.ThrowsAsync<AbpAuthorizationException>(async () =>
{
await _myAuthorizedServiceWithRole.ProtectedByAnotherRole().ConfigureAwait(false);
}).ConfigureAwait(false);
}
[Fact]
public async Task Should_Allow_To_Call_Method_If_Has_No_Role_ProtectedByRole_Async()
{
int result = await _myAuthorizedServiceWithRole.ProtectedByRole().ConfigureAwait(false);
result.ShouldBe(42);
}
[Fact]
public async Task Should_Not_Allow_To_Call_Method_If_Has_No_Role_ProtectedByScheme_Async()
{
await Assert.ThrowsAsync<AbpAuthorizationException>(async () =>
{
await _myAuthorizedServiceWithRole.ProtectedByScheme().ConfigureAwait(false);
}).ConfigureAwait(false);
}
} }
} }

1
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedService1.cs

@ -11,5 +11,6 @@ namespace Volo.Abp.Authorization.TestServices
Task<int> ProtectedByClass(); Task<int> ProtectedByClass();
Task<int> ProtectedByClassAsync(); Task<int> ProtectedByClassAsync();
} }
} }

13
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/IMyAuthorizedServiceWithRole.cs

@ -0,0 +1,13 @@
using System.Threading.Tasks;
namespace Volo.Abp.Authorization.TestServices
{
public interface IMyAuthorizedServiceWithRole
{
Task<int> ProtectedByRole();
Task<int> ProtectedByScheme();
Task<int> ProtectedByAnotherRole();
}
}

2
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedService1.cs

@ -31,4 +31,4 @@ namespace Volo.Abp.Authorization.TestServices
return 42; return 42;
} }
} }
} }

27
framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/TestServices/MyAuthorizedServiceWithRole.cs

@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Authorization.TestServices
{
[Authorize(Roles = "MyRole")]
public class MyAuthorizedServiceWithRole : IMyAuthorizedServiceWithRole, ITransientDependency
{
public virtual Task<int> ProtectedByRole()
{
return Task.FromResult(42);
}
[Authorize(Roles = "MyAnotherRole")]
public virtual Task<int> ProtectedByAnotherRole()
{
return Task.FromResult(42);
}
[Authorize(AuthenticationSchemes = "Bearer")]
public virtual Task<int> ProtectedByScheme()
{
return Task.FromResult(42);
}
}
}
Loading…
Cancel
Save