- ABP Framework version: v8.0.4
- UI Type: Blazor Server
- Database System: EF Core (SQL Server)
- Tiered (for MVC) or Auth Server Separated (for Angular): no
Our customer gives us a certain authorization structure that is not quite standard. Different permissions should grant access to a service method (not just one permission as usual).
Example:
- Role "User" has the permission "UserWrite"
- Role "Agent" has the permission "AgentWrite"
If I use the AuthorizeAttribute twice, the permissions are AND combined. However, I need them with an OR combination.
I tried it with my own AuthorizeAttribute, but failed. It also didn't work in combination with my own AuthorizationHandler, as I couldn't access the AuthorizationService there (-> circular dependency).
The only variant that worked was to implement this directly in the service method:
public virtual async Task<TargetSystemDto> CreateAsync(TargetSystemCreateDto input)
{
var authUserWrite = await AuthorizationService.AuthorizeAsync(_currentPrincipalAccessor.Principal, null, MyProjectPermissions.TargetSystems.UserWrite);
var authAgentWrite = await AuthorizationService.AuthorizeAsync(_currentPrincipalAccessor.Principal, null, MyProjectPermissions.TargetSystems.AgentWrite);
if (!authUserWrite.Succeeded && !authAgentWrite.Succeeded)
{
throw new AbpAuthorizationException();
}
var targetSystem = await _targetSystemManager.CreateAsync(...);
return ObjectMapper.Map<TargetSystem, TargetSystemDto>(targetSystem);
}
But I would prefer to have this in an attribute. So that I could call it up as follows, for example:
[AuthorizeWithOrCondition(MyProjectPermissions.TargetSystems.AgentWrite, MyProjectPermissions.TargetSystems.UserWrite)]
How could this be realized? There must be a way...
Thanks, Adrian
2 Answer(s)
-
0
Hello,
please check out pull request https://github.com/abpframework/abp/pull/10152#issue-1007619207
Thanks
-
0
Thanks for the hint and the link.
I have now implemented this as follows:
AppService method:
[AuthorizeWithOrCondition(MyProjectPermissions.TargetSystems.UserWrite, MyProjectPermissions.TargetSystems.AgentWrite)] public virtual async Task CreateAsync(TargetSystemCreateDto input) { ... }
AuthorizeAttribute:
public class AuthorizeWithOrConditionAttribute : AuthorizeAttribute, IAuthorizationRequirementData { public string[] PermissionNames { get; } public AuthorizeWithOrConditionAttribute(params string[] permissionNames) { PermissionNames = permissionNames; } public IEnumerable<IAuthorizationRequirement> GetRequirements() { yield return new PermissionsRequirement(PermissionNames, requiresAll: false); } }