Base solution for your next web application
Open Closed

Attributes / Filters for Custom Entity-based Permission System #8294


User avatar
0
cyklussoftware created

Hello,

I am using ASP.NET Zero v7.1 with .NET Core 2.2 and Angular.

In my application, we have many Organization entities. Organizations needs their own permission/authorization system so that members of the organization can be given different roles and abilities within the Organization. We refer to the default ASP.NET Zero permission system as the "Global Permission" system and the Organization based permission system as the "Organization Permission" system.

Our Organization Permission system is not meant to be as comprehensive as the Global Permission system. We simply have 4 Permission Levels with a predefined set of abilities. For example:

  • The Level 3 Permission Level can add Members and modify Organization details like it's logo and description.
  • The Level 2 Permission Level can create/update/delete Announcements or other Organization specific entities unrelated to Member management
  • The Level 1 Permission Level has no special permissions, but can see Organization specific entities assigned to them (or other private Organization information)
  • The "Public" Permission Level doesn't actually exist. When a user is in the "Public" Permission Level, it means that a user doesn't belong to the Orgnaization and can only see Organization specific entities marked as "IsPublic"

Orgnanization specific entities like Announcement can be marked as IsPublic OR be assigned to 1 or more Permission Levels.

Now, when a User wants to see a list of Announcements for an Organization, we query the database for all Announcements related to Organization 1 and check 4 things in the WHERE condition of our query:

  • Does the User have any Global Permissions related to Announcements? If yes, then he can view ALL Announcements
  • Is the Announcement Public? If yes, then he can view the Announcement
  • Does the User have a Level 2 or higher Permission Level for the Organization that this Announcement belongs to? If yes, then he can view the Announcement.
  • Is the Announcement assigned to his Permission Level in the Organization? If yes, then he can view the Announcement.

Checking the 4 conditions in the WHERE of our query works, but it requires us to query for a list of the User's Memberships before doing the Announcement query so that the Announcement query can check the User's permission for each Announcement without doing extra JOIN / GROUP BY logic. I am working to make this easier and more efficient by using a TypedCache and a helper class.

When it comes to creating/updating/deleting Announcements, a User must have Global Permission OR Level 2 or higher for the Organization. Right now, this is done doing another query inside of each Create/Update/Delete method (I already have a helper class doing it), but I would like to abstract the permission checking logic into an Attribute or Filter, if possible, so that I don't have to write as much code each time I create a new create/edit/delete endpoint.

Hopefully what I have described makes sense to some degree. Based on what I've described, do you think it's worth trying to go down the custom Authorization Filter / Authorization Policy route for create/update/delete? Or do you think it makes sense to keep querying like I am because it is a non-standard Authorization scheme?

Thanks!


2 Answer(s)