How to implement Permission Based Access Control with Asp.Net Core

adem caglin :

I am trying to implement permission based access control with aspnet core. For dynamically managing user roles and permissions(create_product, delete_product etc.), they are stored in the database. Data Model is like http://i.stack.imgur.com/CHMPE.png

Before aspnet core (in MVC 5) i was using custom AuthorizeAttribute like below to handle the issue:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    private readonly string _permissionName { get; set; }
    [Inject]
    public IAccessControlService _accessControlService { get; set; }

    public CustomAuthorizeAttribute(string permissionName = "")
    {
        _permissionName = permissionName;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        var user = _accessControlService.GetUser();
        if (PermissionName != "" && !user.HasPermission(_permissionName))
        {
            // set error result
            filterContext.HttpContext.Response.StatusCode = 403;
            return;
        }
        filterContext.HttpContext.Items["CUSTOM_USER"] = user;
    }
}

Then i was using it in action method like below:

[HttpGet]
[CustomAuthorize(PermissionEnum.PERSON_LIST)]
public ActionResult Index(PersonListQuery query){ }

Additionally, i was using HttpContext.Items["CUSTOM_USER"] in views to show or hide html part:

@if (CurrentUser.HasPermission("<Permission Name>"))
{

}

When i decided to switch aspnet core, all my plan was failed. Because there was no virtual OnAuthorization method in the AuthorizeAttribute. I tried some ways to solve problem. Those are below:

  • Using new policy based authorization(i think it is not suitable for my scenerio)

  • Using custom AuthorizeAttribute and AuthorizationFilter(i read this post https://stackoverflow.com/a/35863514/5426333 but i couldn’t change it properly)

  • Using custom middleware(how to get AuthorizeAttribute of current action?)

  • Using ActionFilter(is it correct for security purpose?)

I couldn’t decide which way is the best for my scenerio and how to implement it.

First question: Is MVC5 implementation bad practice?

Second question: Do you have any suggest to implement aspnet core?

Tseng :

Based on the comments, here an example on how to use the policy based authorization:

public class PermissionRequirement : IAuthorizationRequirement
{
    public PermissionRequirement(PermissionEnum permission)
    {
         Permission = permission;
    }

    public PermissionEnum Permission { get; }
}

public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
    private readonly IUserPermissionsRepository permissionRepository;

    public PermissionHandler(IUserPermissionsRepository permissionRepository)
    {
        if(permissionRepository == null)
            throw new ArgumentNullException(nameof(permissionRepository));

        this.permissionRepository = permissionRepository;
    }

    protected override void Handle(AuthorizationContext context, PermissionRequirement requirement)
    {
        if(context.User == null)
        {
            // no user authorizedd. Alternatively call context.Fail() to ensure a failure 
            // as another handler for this requirement may succeed
            return null;
        }

        bool hasPermission = permissionRepository.CheckPermissionForUser(context.User, requirement.Permission);
        if (hasPermission)
        {
            context.Succeed(requirement);
        }
    }
}

And register it in your Startup class:

services.AddAuthorization(options =>
{
    UserDbContext context = ...;
    foreach(var permission in context.Permissions) 
    {
        // assuming .Permission is enum
        options.AddPolicy(permission.Permission.ToString(),
            policy => policy.Requirements.Add(new PermissionRequirement(permission.Permission)));
    }
});

// Register it as scope, because it uses Repository that probably uses dbcontext
services.AddScope<IAuthorizationHandler, PermissionHandler>();

And finally in the controller

[HttpGet]
[Authorize(Policy = PermissionEnum.PERSON_LIST.ToString())]
public ActionResult Index(PersonListQuery query)
{
    ...
}

The advantage of this solution is that you can also have multiple handlers for a requirement, i.e. if first one succeed the second handler can determine it's a fail and you can use it with resource based authorization with little extra effort.

The policy based approach is the preferred way to do it by the ASP.NET Core team.

From blowdart:

We don't want you writing custom authorize attributes. If you need to do that we've done something wrong. Instead you should be writing authorization requirements.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to implement permission based authorization in ASP.net core Identity?

Using Authorization filters to Implement permission based authorization in asp.net core

How to implement Localization ASP net CORE MVC

How to modify file access control in .NET Core

How can I implement slug-based routing in ASP .NET Core?

How to implement dynamic resource permission in asp.net MVC?

ASP.NET Core 2.2. Razor Pages - How to populate a form control based on another field

how do I implement role based access control in firebase

'Access-Control-Allow-Origin' in ASP.NET Core 6

How to implement Infinite Scrolling in ASP .Net for DataGrid Control

How to implement cascading DropDownList ASP.Net control?

How to access cookie asp.net core

How to access current HttpContext in ASP.NET Core 2 Custom Policy-Based Authorization with AuthorizationHandlerContext

Disable Access-Control-Allow-Origin in ASP.Net and ASP.Net Core

How to implement Identity in ASP.NET Core 2.2

How to implement the IConfiguration interface in ASP.NET Core for Dapper usage?

How do I implement a checkbox list in ASP.NET Core?

How to correctly implement ExceptionFilterAttribute in ASP.NET Core

How to implement pagination in asp.net core razor pages

How to implement machineKey in ASP.NET Core 2.0

how implement Owin pipeline using Asp.net core

How to implement angular 4 server prerendering in ASP.NET Core

How to implement resource files localization ASP-NET.core?

How to implement custom ValidateAntiforgeryTokenAuthorizationFilter in ASP.NET Core 3.1

How to implement search filter in ASP.NET Core Web API

How to implement an ASP.NET Core controller supporting Razor and Angular?

ASP Net core - How to implement background services localization?

How to implement a setup page in ASP.NET Core?

Role-based access control (RBAC) vs. Claims-based access control (CBAC) in ASP.NET MVC