7

MVC 3 アプリケーションのコントローラーでアクション メソッドを装飾している可能性のある認証属性を調べようとしています。基本的に ActionLink のラッパーである独自の HtmlHelper 拡張メソッドでこれを行っています (実行時に利用できる情報のコンテキストを提供するため)。私は基本的な解決策を用意していますが、オーバーロードされたメソッドがそれを爆発させました。フレームワークが内部的にURLをアクションメソッドに解決していることは知っていますが、System.Web.Mvc.LinkExtensionsのコードを調べた後でも、それがどのように起こっているのか正確にはわかりません。この問題に取り組むために。

関連するメソッドを解決するためのこれまでのコードは次のとおりです。

private static bool _IsUserAuthorized(HtmlHelper html,
  string controllerName, string actionName)
{
  controllerName = controllerName ??
    html.ViewContext.RouteData.GetRequiredString("controller");

  var factory = ControllerBuilder.Current.GetControllerFactory();
  var controller = factory.CreateController(
    html.ViewContext.RequestContext, controllerName);

  Type controllerType = controller.GetType();
  var methodInfo = controllerType.GetMethod(actionName,
    BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

  ... check authentication
}

したがって、私の現在の問題は、メソッドがオーバーライドされると、「あいまいな一致が見つかりました」という例外が発生することです。RouteValues を処理してメソッドのパラメーターを解決し、正しいパラメーターを明確に識別できるようにする必要があると思います。誰かがこれを行う方法についていくつかの指針を持っていますか? あるいは、フレームワークは、必要な正確なメソッドを解決する手段をすでに提供していますか?

本当にありがとう!

4

2 に答える 2

2

編集:このページからの洞察を含むようにメソッドを更新しました。この最終バージョンは、要求されたアクション メソッドの AuthorizationFilters を調べて、ユーザーがアクションを実行する権限を持っているかどうかを確認します。

そこで、System.Web.Mvc.ControllerActionInvoker を調べて、必要なメソッドとコンストラクターを見つけました。ControllerDescriptor.FindAction() がキーになりました。以下に、すべての属性を取得する、私が書いたメソッドをコピーしました

private static bool _IsUserAuthorized(HtmlHelper htmlHelper,
  string controllerName, string actionName)
{
  ControllerContext controllerContext = null;
  //if controllerName is null or empty, we'll use the 
  // current controller in HtmlHelper.ViewContext.
  if (string.IsNullOrEmpty(controllerName))
  {
    controllerContext = htmlHelper.ViewContext.Controller.ControllerContext;
  }
  else //use the controller factory to get the requested controller
  {
    var factory = ControllerBuilder.Current.GetControllerFactory();
    ControllerBase controller = (ControllerBase)factory.CreateController(
      htmlHelper.ViewContext.RequestContext, controllerName);
    controllerContext = new ControllerContext(
      htmlHelper.ViewContext.RequestContext, controller);
  }

  Type controllerType = controllerContext.Controller.GetType();
  ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
  ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
  if (actionDescriptor == null)
    return false;

  FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(
    controllerContext, actionDescriptor));

  AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);
  foreach (IAuthorizationFilter authFilter in filters.AuthorizationFilters)
  {
    authFilter.OnAuthorization(authContext);
    if (authContext.Result != null)
      return false;
  }
  return true;
}
于 2012-05-01T13:37:30.897 に答える
0

認証コードを追加する通常の方法は、認証フィルターを使用することです。

IAuthorizationFilter.OnAuthorizationは、プロパティを持つAuthorizationContextオブジェクトを提供しActionDescriptorます。

于 2012-04-30T20:59:37.320 に答える