8

I am creating an application in that there is role-based module management and it is changed anytime by anytime. Scenario:

  • If a user has access to create and view Employee than a user can do only create and view employees but in future admin change user's role from creating and view to view and delete than a user can only do that activity.

I try with [Authorize(Roles ="Staff")] but if admin change runtime than it isn't managed.

Can anyone look into this and get back to me?

19
  • Authorize(Roles ="Staff") makes sure that user with role Staff only can access this action... So if user is removed from this role, user will not be able to access this.. Is this not happening? Commented Nov 7, 2019 at 7:43
  • As far as I know this is not possible and maybe not a good idea. Users should log out and log back in for the new roles to apply. You might even render the page differently. Commented Nov 7, 2019 at 7:56
  • Assuming you're using cookie or jwt bearer token: the user's claims/roles are persisted in the cookie/token, you have to sign out the user and sign in the user again to make sure it gets a fresh cookie/token. Commented Nov 7, 2019 at 8:23
  • Hi, @itminus Currently, the initial phase is running so at a time of login user get the role and available roles list like Create Employee, View Employee and @Emad Yes I need changes at time of login if there are any changes during live session then there is no affect in a role. Is it possible? Commented Nov 7, 2019 at 9:09
  • @DeepSoni can we Implement custom Authorize attributes so we can achieve this requirement. Please suggest so we can move ahead. Commented Nov 12, 2019 at 4:47

2 Answers 2

2

This is a complicated question and there isn't a right answer but there are several ways to do it. First I will assume you are using stateless auth using a claim based jwt the simplest way is writing your own Policy that will read user roles before every request, this is the simplest way to do it and fastest to implement.

internal class DatabaseRoles : IAuthorizationRequirement
    {
        public string Role { get; }

        public DatabaseRoles(string role)
        {
            Role = role;
        }
    }

    internal class DatabaseRolesHandler : AuthorizationHandler<DatabaseRoles>
    {
        private readonly UserManager<IdentityUser> userManager;

        public DatabaseRolesHandler(UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager)
        {
            this.userManager = userManager;
        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, DatabaseRoles requirement)
        {
            //NOTE this is the out of the box implementation of roles and simple query to get the roles from the EF backed database. I would recoment makeing a custom privelages store for this and not using roles for this but access rights
            var user = await userManager.FindByIdAsync(userManager.GetUserId(context.User));
            if (await userManager.IsInRoleAsync(user, requirement.Role))
            {
                context.Succeed(requirement);
            }
        }

    }

But this solution is not that performant because it requires a call to the database on every request. This is fine on small loads but might create problems in traffic. The other way is to reevoke the all user tokens when the roles change but this is super complicated. I am sure if you create some fast access store for roles like redis there will be no issues to do the check on every call. Also I do not recommend creating your own user storage because it's a nightmare to maintain and keep up to date in regards to security standards.

Sign up to request clarification or add additional context in comments.

6 Comments

Hi, Thanks for your answer. I have tried with your solution but at every processing of Index, Create, Edit or Any other operation this method is calling and one issue is If there is a dashboard there is public available there is no role given to that particular module then it is not visible to anyone as per your code.
@DeepSoni Just one thing to point out the code if demonstrative would not recommend using it as is. You should customize this to fit your need. The point of this is as example of resource based auth. The query should check your database with user id with a custom query.
Thanks for the reply. Let me try with your reference and solution.
I try currently when I make reference to Microsoft Doc for resource-based authorization then IDocumentRepository is not able to use. it shows me to install UmbracoCMS. Can you please figure out?
O so it's UmbracoCMS specific question I am really not that familiar with it might be best to add UmbracoCMS tag and code you tried to do so someone with experience to look at it. But from what I can tell it should work anywhere as long as you make the correct query to UmbracoCMS.
|
-1

If you are using Session/Cookie to store the logged in user details, you can empty the details whenever Admin make role changes. On every action you can check the role in Session/Cookie and move forward. Now as soon as user clicks anywhere on the screen which hits the controller. The condition will be checked and the User will be logged out as the Session/Cookie object is empty.

2 Comments

Hi @BansariSoni. Thanks for the answer. It doesn't make sense that remove session every time and ask for login to user. It only like a patch(Fixed) in application so need some proper answer that is even acceptable or some hint to figure out answer.
If role is in session then according to me there can me only two option either changing the session variable or removing it. Here you can do one other thing like when admin changes role you can check if that userid exists in the session if yes than set a flag in session. Then you can create a cron job which refreshes the page every 5 mins only if this particular flag is true.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.