9

Asp.Net Web Api を使用しています。接続されたクライアントのアクセス権に基づいて、応答オブジェクトの特定のフィールドを除外できるようにしたいと考えています。

例:

class Foo
{
    [AccessFilter("Uberlord")]
    string Wibble { get; set; }

    string Wobble { get; set; }
}

データWibbleを返す場合、現在のユーザー コンテキストが「Uberlord」の値を満たすことができる場合にのみ、フィールドを返す必要があります。

私が模索している 3 つの方法がありますが、実用的な解決策はありません。

  1. カスタム WebApi MediaTypeFormatter。
  2. カスタム json.net IContractResolver。
  3. 応答オブジェクトを操作するコントローラー用のある種の AOP ラッパー

これらに関する私の問題は次のとおりです。

  • カスタムフォーマッタは、それを行うのに適切な場所ではないように感じますが、唯一のオプションかもしれません.
  • カスタム json シリアライザーは現在のコンテキストにアクセスできないため、解決する必要があります。
  • 最初の 2 つのオプションでは、各応答形式、json、xml、一部のカスタム形式などに特定の実装が必要になります。これは、別の応答タイプがサポートされている場合、機密データの漏洩を防ぐためにカスタム フォーマッタ/シリアライザーが必要であることを意味します。
  • AOP コントローラー ラッパーには、多くのリフレクションが必要です。

追加のボーナスは、同じメカニズムを使用して受信リクエスト オブジェクトのフィールドから値を削除することです。

明らかなフックを見逃していませんか? これは別の方法で解決されましたか?

4

2 に答える 2

4

実際には、最初に考えていたよりもはるかに簡単でした。私が気付いていなかったのは、を使用してWeb Api PipelineDelegatingHandlerの要求だけでなく応答も操作できるということです。

ASP.NET Web API メッセージのライフサイクル

委任ハンドラー


委任ハンドラーはメッセージ パイプラインの拡張ポイントであり、リクエストを残りのパイプラインに渡す前にメッセージを送信できます。戻る途中の応答メッセージも委任ハンドラーを通過する必要があるため、この拡張ポイントで応答を監視/フィルター処理/更新することもできます。

必要に応じてハンドラーを委任すると、残りのパイプラインもバイパスして、HTTP 応答自体を送り返すことができます。

以下は、応答オブジェクトを操作するか、完全に置き換えることができる DelegatingHandler の実装例です。

public class ResponseDataFilterHandler : DelegatingHandler
{
    protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        return base.SendAsync(request, cancellationToken)
            .ContinueWith(task =>
            {
                var response = task.Result;

                //Manipulate content here
                var content = response.Content as ObjectContent;
                if (content != null && content.Value != null)
                {
                    ((SomeObject)content.Value).SomeProperty = null;
                }

                //Or replace the content
                response.Content = new ObjectContent(typeof(object), new object(), new JsonMediaTypeFormatter());

                return response;
            });
    }
}

委任ハンドラーを実装してパイプラインに追加する方法に関する Microsoft の記事。ASP.NET Web API の HTTP メッセージ ハンドラー

于 2013-07-04T13:55:50.393 に答える
0

ここで同様の質問があります: ASP.NET WebAPI Conditional Serialization based on User Role

私が思いついた提案された解決策は、ユーザーの役割に基づいて適切なフォーマッターを設定するために Initalize 関数をオーバーライドする BaseApiController から ApiController を継承させることです。この方法で行くかどうかはまだ決めていませんが、おそらくうまくいくでしょう。

protected override void Initialize(System.Web.Http.Controllers.HttpControllerContext controllerContext)
{
    base.Initialize(controllerContext);
    // If the user is in a sensitive-data access role
    controllerContext.Configuration.Formatters.Add(/*My Formatter*/);
    // Otherwise use the default ones added in global app_start that defaults to remove sensitive data
}
于 2013-07-03T16:03:04.957 に答える