Can I programatically check whether a user is authorized for a given controller method?

148 views Asked by At

[Please note this question is about DotNet Core 1.1]

I have a controller method in my ItemsController class attributed as follows to restrict the ability to access the method to users in an administrator group:

    [Authorize(Roles = @"MYDOMAIN\ThisApplicationAdmins")]
    [HttpDelete("/items/{itemsName}")]
    public ActionResult DeleteItem(string itemName)
    {
        // Dangerous code here.
    }

This works correctly.

I would, additionally, like to remove the red X in the application that triggers this controller method for users who cannot access the method. I know that I could check to see whether the user is in the correct AD group but this requires me to duplicate my authorization logic and exposes me to the possibility that I will update the attribute, but not the user interface check.

Does there exist a way to query ASP DotNet core to ask "Is user X authorized to access method ItemsController.DeleteItem()?" and have that question answered by the same middleware that is responsible for processing the attribute?

1

There are 1 answers

0
Pooja Suryawanshi On

Yes,U can check in middle level between UI and controller that particular user has access to requested Controller or not.

/We need to add somewhere in ur View below async method/

@if (await Url.HasAccessToController(urlActionContext))
{
    <p>You have access</p>
}

Implemntation of the method:-

public static async Task<bool> HasAccess(this IUrlHelper Helper, UrlActionContext ActionContext, string httpMethod = "GET" )
{
//U need to Implement this method as per your needs

    var httpContext = Helper.ActionContext.HttpContext;

    var routeValues = new RouteValueDictionary(ActionContext.Values);
    routeValues["action"] = ActionContext.Action;
    routeValues["controller"] = ActionContext.Controller;          

    var path = Helper.Action(ActionContext);

    var features = new FeatureCollection();
    features.Set<IHttpRequestFeature>(new HttpRequestFeature()
    {
        Method = httpMethod, 
        Path = path,

    });

    var ctx = new DefaultHttpContext(features);      

    var routeContext = new RouteContext(ctx);

    foreach (var entry in routeValues)
    {
        routeContext.RouteData.Values.Add(entry.Key, entry.Value);
    }

    var actionSelector = httpContext.RequestServices.GetRequiredService<IActionSelector>();

    var provider = httpContext.RequestServices.GetRequiredService<IActionDescriptorCollectionProvider>();       
    var actionDescriptors = actionSelector.SelectCandidates(routeContext);

    var actionDescriptor = actionSelector.SelectBestCandidate(routeContext, actionDescriptors);

    var authService = httpContext.RequestServices.GetRequiredService<IAuthorizationService>();

    var ok = await authService.AuthorizeAsync(httpContext.User, actionDescriptor, "YOUR_POLICY"); 

    return ok;

}