Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set runtime authentication in ASP.NET Core?

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?

like image 971
Deep Soni Avatar asked Nov 07 '19 07:11

Deep Soni


People also ask

How do you pass basic authentication in header .NET Core?

Basic Authentication works by adding an Authorization header into a HTTP request. The value of the Authorization header must be Basic, followed by a space, followed by the username and password separated by a colon. The username and password are encoded using Base64.

How do I change Authentication in Visual Studio?

Change authentication mode with SSMSIn SQL Server Management Studio Object Explorer, right-click the server, and then click Properties. On the Security page, under Server authentication, select the new server authentication mode, and then click OK.


1 Answers

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.

like image 51
Filip Cordas Avatar answered Oct 14 '22 13:10

Filip Cordas