Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to? : RBAC implementation in React SPA + Django Backend using Azure AD token claims, roles, groups. #342

Open
sachingaikwad123 opened this issue Jun 28, 2024 · 3 comments

Comments

@sachingaikwad123
Copy link

sachingaikwad123 commented Jun 28, 2024

I am looking for guidance on how to implement RBAC using django-auth-adfs in following scenario. [There is no 'discussion' option hence creating 'issue' to discuss with community.]

Scenario/Setup.

  1. Backend Service: Django DRF REST APIs
    a. Manages 'Employee' information.
    b. Manage 'Team' information. Team 'Model' has 'Employee's.
    c. Employees will be added/deleted from Team from time to time. Such 'management action' of addition/deletion to 'Team' should automatically result in 'adding' access or 'revoking' access - if we have done some initial setup for RBAC.
    d. 'Group' Model: Not yet defined. But, thinking of defining 'Group' Model. A 'Team' can have associated 'Group'.
    e. 'Group' can exist without 'Team' Model as well. But, every 'Team' must have a 'Group'.
    f. Group creation/deletion should be synced to Azure AD Groups (may be via Celery Task)
    g. 'Group' membership adding/deleting should also be synced to Azure AD Groups (may be via Celery Task)
  2. Frontend App: React SPA Application
    a. User can login to React SPA App with Microsoft login id/password/MFA. This works. Able to get ID Token. Able to get 'MS Graph' access token and call 'MS Graph' API successfully.
    b. User is able to get 'Access Token' for 'Backend Web API'. Able to call 'Backend Web API' successfully.
    c. Backend 'Access Token' contains:
    i. Groups: But they are only GUIDS (because it is Azure AD Cloud Only setup)
    ii. Roles: Contains 'roles' defined in 'Azure AD App'.
  3. Authentication/Identity Server: Azure AD (cloud ONLY)
    a. Defined 'role' in 'Azure AD App' and assigned to 'Users'. [I will assign to 'Group' when I upgrade my license]

Requirements:

  1. Management Team should be able to update 'Teams' information in 'Backend Service' (via some React Portal - not relevant) and this should automatically result in 'permission/access' 'granted' or 'revoked' for various services/apps in our tech infrastructure for company.
  2. React SPA need to have some 'conditional code' to show some features/UI/operations. We should be able to 'define roles' and assign to 'Groups'.
  3. Backend Service (Django) should also have 'permissions' based on roles/groups on various REST APIs (views).
  4. These 'roles' or 'groups' should be somehow linked to 'Groups' defined for 'Teams' so that 'automatic access control' requirement mentioned in (1) is effective.
  5. If we come up with any new 'React SPA' or new 'Backend Service' (Django) in future, they should be able to follow similar approach easily and implement authorization for their service/apps. If required, they can also suggest and add new 'Teams' in this first/main 'Backend Service' (Django).

Solution-1:

  1. Create 'Groups' in Django Backend Service. Sync them to Azure AD periodically.
  2. Define 'roles' n 'Azure AD App'. Assign 'roles' to 'Azure AD Groups'. [Hierarchical Azure AD Groups can be created to manage this well.]
  3. Get 'roles' in 'access token'.
  4. Write code in Django Backend Service by checking if 'request.user.token.roles' contains [Required set of role names] for each view. 'Required set of role names' is hardcoded in Django Backend Service code.

Problems with Solution-1:

  1. 'Required set of groups (roles)' is hard code in Django Backend Code. Any change will require 'Backend Service' re-deployment.
    a. Can we expose this by defining custom permission model and updating this dynamically if there are any changes?

Solution-2:

  1. Create 'Groups' in Django Backend Service. Sync them to Azure AD periodically.
  2. Define 'roles' n 'Azure AD App'. Assign 'roles' to 'Azure AD Groups'. [Hierarchical Azure AD Groups can be created to manage this well.]
  3. Get 'roles' in 'access token'.
  4. Q: With GROUPS_CLAIM = roles and MIRROR_GROUPS = True, I think 'groups' with same name as 'roles' will be created in Django. User will be added or removed from these group on every request. I am yet to try this. Please confirm if my understanding is correct.
  5. Write code in Django Backend Service by checking if 'request.user' belongs to [Required set of groups] for each view. 'Required set of groups' is hardcoded in Django Backend Service code. These groups are same as 'role names'. I think new 'roles' get added less often so, this hardcoding should be fine.

Problems with Solution-2:

  1. For every request received, user group membership is completely erased and group membership is added based on 'roles' in token. Too much churning for every request?

Questions:

  1. There are inline questions as well in above descriptions. If someone can help in that, it will be great.
  2. Does django-auth-adfs automatically give us all 'claims' as part of 'request' OR I will need to write my own middleware for it?
  3. How can I implement RBAC in this setup and requirements? I am not happy with both above solutions due to problems mentioned with it. Anyone has any recommendations for solution?

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@sachingaikwad123
Copy link
Author

Ping! Anyone has any thoughts on this?

@tim-schilling
Copy link
Member

tim-schilling commented Jul 2, 2024

You may want to start a thread on the django forum.

@JonasKs
Copy link
Member

JonasKs commented Jul 2, 2024

I'm on vacation so I won't read through it all now, sorry. How ever, this package creates native roles in Django. You should be able to do RBAC as you would with any Django role.

The Django Discord/forum is a more appropriate place to ask this question. 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants