5

プロジェクトに Asp.Net WebAPI を使用しています。私は現在、認証と承認に取り組んでいます。

リクエストの HTTP 認証ヘッダーをチェックし、ID とユーザー プロファイルを作成する messageHandler があります。ただし、コントローラー アクション (またはコントローラーのみ) に、アクションが必要とする可能性のあるクレームを付けたいと考えています (ユーザーが持つことができるクレームがたくさんあるので、すべてをロードしたくありません)。

例えば:

public class MyController : ApiController
{
    [LoadClaims("SomeClaim", "SomeOtherClaim", "etc")]
    public string Get()
    {
        if (HasClaim("SomeClaim"))
            return "Awesome";

        return "Bummer";
    }
}

認証メッセージ ハンドラー内で、属性を確認し、必要なものだけに基づいて DB からクレームを取得できるようにしたいと考えています。そのためには、ルートに基づいてヒットするコントローラーとアクションを知る必要があります。

 protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {
...

            var routeData = request.GetRouteData();
            object controllerName;
            object actionName;
            routeData.Values.TryGetValue("controller", out controllerName);
...

だから私はそれを得ることができます。しかし今、これを反映できるタイプに変換する必要がありますが、私が持っているのはコントローラー名だけです (完全なクラス名や名前空間でさえありません)。これを、属性などを取得するために反映できるものにするにはどうすればよいですか?

DefaultHttpControllerSelectorWebAPIスタックがどのようにそれを行うかを調べていますが、HttpControllerTypeCache. これは内部クラスなので、インスタンスを作成できません。ターゲットコントローラーのタイプを取得する正しい方法は何ですか?

4

2 に答える 2

7

グローバル サービス ロケーターを使用して、型リゾルバーに自分でアクセスできます。

var controllerTypeResolver = GlobalConfiguration.Configuration.Services.GetHttpControllerTypeResolver();
var controllerTypes = controllerTypeResolver.GetControllerTypes(GlobalConfiguration.Configuration.Services.GetAssembliesResolver());
var controllerType = controllerTypes.SingleOrDefault(ct => ct.Name == string.Format("{0}Controller", controllerName));

おそらく、結果のキャッシュを実行したいと思うでしょう (コントローラ セレクタのように)。しかし、このアプローチはうまくいくはずです。

しかし

このロジックを、委任ハンドラーではなく、コントローラー上にあるカスタム承認フィルターに移動した方がよい場合があります。コントローラーのタイプを知る必要がある場合は、ControllerSelector を正常に動作させることもできます。おそらく、ロード クレーム属性を承認アクション フィルター属性に変更した場合、パラメーターとして渡されたクレームをロードし、そこにプリンシパルとクレームを設定するだけでよいでしょうか?

于 2013-02-23T21:56:20.497 に答える
1

まだ設定されているDelegatingHandler場合は、コントローラーセレクターインスタンス自体を取得できます。これにより、より効率的になります。

var controllerSelector = GlobalConfiguration.Configuration.Services.GetHttpControllerSelector();
var controllerDescriptor = controllerSelector.SelectController( request );
于 2013-11-06T15:13:20.453 に答える