ASP.NET Core Custom Authorization

随声附和 提交于 2020-12-12 09:37:52

问题


I need to implement role based authorization on a .NET 5 API but the thing is that we don't want to decorate all the controllers with attributes and a list of roles, because all that configuration will come from either a config file (JSON) or an external service (TBD), in a way that roles will be mapped to controllers and actions and we would want to have something that centralizes all this logic, in a similar way we did before with Authentication Filters and Attributes.

I've been reading that now the idea from MS is that everything is handled with policies and requirements, but I don't know how to fit all that into our desired schema. Most of all because I don't see (or can't see) how can I access the Controller and Action's descriptors to know where I'm standing when I perform the authorization process.

Is there any way to achieve this on this new model?

EDIT: I found a way to get controller and action descriptors in order to do part of what I intended. Based on some other questions and articles I read and some tinkering on my own, I got the following:

public class AuthorizationFilter : IAsyncAuthorizationFilter
{
    public Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var descriptor = (ControllerActionDescriptor)context.ActionDescriptor; //<<-- this is the key casting :)
        var ctrlName = descriptor.ControllerName;
        var actionName = descriptor.ActionName;
        var userPrincipal = context.HttpContext.User;
        //DO STUFF AND DECIDE RESULT TYPE BASED ON USER CLAIMS AND CURRENT CONTROLLER AND ACTION
        context.Result = new ForbidResult();
        context.Result = new UnauthorizedResult();
            
        return Task.CompletedTask;
    }
}

Then I could add this filter the following way:

services.AddControllers(x => x.Filters.Add<AuthorizationFilter>());

This way I could achieve something similar as before with ASP.NET MVC 4/5, but from what I can read, the .NET Core team tried to go away from this path by implementing the IAuthorizationRequirement and AuthorizationHandler<T> mechanism to replace all that, so my doubt remains: is this the correct way to do it in the new .NET Core 3.x / .NET 5 architecture? Or is there some other way I'm overlooking on how to get and process the controller/action being executed and pass it along to an AuthorizationHandler?


回答1:


What you are looking for is called externalized authorization also referred to as attribute-based access control. In this model:

  • authorization logic is decoupled from the application
  • authorization logic is expressed as policies that build on top of attributes
  • attributes are key-value pairs that describe the subject, the action, the resource, and the context of what's going on (A user wants to execute an action on an object at a given time and place)
  • authorization is decided based on those policies in a logical central point (logical because you could very well have multiple instances of that central point colocated with your app for performance reasons). That logical central point in abac is known as the Policy Decision Point (PDP)
  • authorization is enforced based on the response back from the PDP in the place where you want to enforce it. This could be at a method level or at an API level or even a UI level: you choose. The component in charge of enforcing the decision is called a Policy Enforcement Point (PEP).

There's one main standard out there called xacml and its developer-friendly notation called alfa that will let you implement attribute-based access control. It's worth noting this model and approach is applicable to any app (not .NET-specific at all).



来源:https://stackoverflow.com/questions/65153325/asp-net-core-custom-authorization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!