0

I have list of controller actions like,

AController.BAction
AController.CAction
BController.DAction
BController.EAction
...................

I want to call authorization service with authorizationService.AuthorizeAsync(User, and passing specific action and controller to see whether user have this permission for all/some of these controller actions?

Why I need this? Because I have list of Menus which points to controller actions. I just need to check which controller action user have permission before making it visible to user.

Imran Qadir Baksh - Baloch
  • 32,612
  • 68
  • 179
  • 322
  • normally the JWT Token used to authenticate the user, should have the permissions and you know it for each request, but it's just one more way to do the same... if you want to take the `AuthorizeAsync` path, [this article](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/views?view=aspnetcore-7.0) might give you better help – balexandre Apr 14 '23 at 06:01
  • If you are using JWT you can extract token claim or you can use [`Authorize attribute`](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-7.0#multiple-policy-evaluation) before your action in order to [`check claim or permission`](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-7.0#adding-claims-checks). – Md Farid Uddin Kiron Apr 14 '23 at 09:21
  • This question might help you forward, https://stackoverflow.com/questions/14382336/determine-if-a-user-will-have-access-to-a-given-controller-action-based-on-role – Zephire Apr 26 '23 at 18:54

1 Answers1

1

I tried as below for Policy based Authorization:

inject IEnumerable<EndpointDataSource> into controller(or your target Service)

codes:

            var endpoints = _endpointSources.SelectMany(es => es.Endpoints).OfType<RouteEndpoint>();
            // a dictionary records all endpoints require authorization
            var targetdic = new Dictionary<string, string>();
            foreach(var ep in endpoints)
            {

                //read  endpoint's controller name/action name from  ControllerActionDescriptor
                var descriptor = ep.Metadata.OfType<ControllerActionDescriptor>().FirstOrDefault();
                //read httpmethod from HttpMethodMetadata
                var httpmethod=ep.Metadata.OfType<HttpMethodMetadata>().FirstOrDefault()?.HttpMethods.First()??"GET";
                //read authdata
                var authdatalist = ep.Metadata.GetOrderedMetadata<IAuthorizeData>();
                foreach(var authdata in authdatalist)
                {
                    //logical may not correct here,you may need to validate auth scheme?
                    if (authdata.Policy != null&& httpmethod==HttpMethod.Get.Method)
                    {
                        var path = String.Format("/{0}/{1}", descriptor?.ControllerName, descriptor?.ActionName);
                        targetdic.Add(path, authdata.Policy);
                        break;
                    }                    
                }
            }

Tried with project as below:

enter image description here

detailed controllers and actions:

HomeController:

enter image description here

AnotherController:

enter image description here

When I debug,result:

enter image description here

Now you could try follow this doc:

@if ((await AuthorizationService.AuthorizeAsync(User, dic["Key"])).Succeeded)
{
    //your link here accroding to  the Key
}

based on abdusco's answer ,and this case,Hopes help

Ruikai Feng
  • 6,823
  • 1
  • 2
  • 11