Open Closed

AuthorizeAttribute to combine multiple permissions with OR condition #7191


User avatar
0
ageiter created
  • 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)
  • User Avatar
    0
    Anjali_Musmade created
    Support Team Support Team Member

    Hello,

    please check out pull request https://github.com/abpframework/abp/pull/10152#issue-1007619207

    Thanks

  • User Avatar
    0
    ageiter created

    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);
            }
        }
    
Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19