MVC equivalent of Webforms “UrlAuthorizationModule

2019-06-03 19:50发布

So I have this Controller:

namespace MyNamespace.Controllers
{
  [Authorize(Roles="Administrator")]
  public class MyController : Controller

  public ActionResult Index()
  {
   ...

As you can see, only users with the Administrator role have access to MyController's Action methods.

So, from somewhere else (another controller, another class in my library class, etc) how do I check if Current.User.Identity.Name has access to MyController?

Something that works like "UrlAuthorizationModule.CheckUrlAccessForPrincipal" for WebForms.

1条回答
Bombasti
2楼-- · 2019-06-03 20:53

You would have to read the information from the other controller. This can be done by instantiating its context and the Descriptor, then instantiating the AuthorizationContext for that controller and read the filter info.

This is how you can do it

private bool ActionIsAccessibleToUser(string actionName, ControllerBase controllerBase)
{
    // Get controller context.
    var controllerContext = new ControllerContext(this.ControllerContext.RequestContext, controllerBase);

    // Get controller descriptor.
    var controllerDescriptor = new ReflectedControllerDescriptor(controllerBase.GetType());

    // Get action descriptor.
    var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);

    // Check on authorization.
    return ActionIsAuthorized(actionDescriptor, controllerContext);
}

private bool ActionIsAuthorized(ActionDescriptor actionDescriptor, ControllerContext controllerContext)
{
    if (actionDescriptor == null)
    {
        // Action does not exist.
        return false;
    }

    // Get authorization context fo controller.
    AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);

    // run each auth filter until on fails
    // performance could be improved by some caching
    var filters = FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor);
    FilterInfo filterInfo = new FilterInfo(filters);

    foreach (IAuthorizationFilter authFilter in filterInfo.AuthorizationFilters)
    {
        // Attempt authorization.
        authFilter.OnAuthorization(authContext);

        // If result is non-null, user is not authorized.
        if (authContext.Result != null)
        {
            return false;
        }
    }

    // Assume user is authorized.
    return true;
}
查看更多
登录 后发表回答