25

私が見るように、私はパイプラインに私のものを差し込むための3つの可能な場所があります

1)     AuthorizationFilters

2)     Action Filters

3)     DelegatingHandler

最も明白なものはAuthorizationFiltersで、カスタムの承認属性でアクション/コントローラーを装飾できます。MyCustomAuthorizationAttribute言う..。

HTTPメッセージハンドラーは処理パイプラインの最初の段階にあるためです。そこに入れるのは意味がありますか?

私にとっての承認とは、認証後にクライアントに渡されるヘッダーのトークンをチェックすることを意味します。

4

1 に答える 1

37

2014年7月の更新

私の最初の答えはWebApi1をカバーしていました。WebApi2ではいくつかの変更がありました。つまり、認証ロジックをもう少しエレガントなものIAuthenticationFilterから移動できるという意味があります。DelegatingHandler

ここには、IAuthenticationFilterの実装を提供し、その導入の背景を説明するNugetプロジェクトがあります。

OWINミドルウェアは、認証ロジックを実装するのにおそらく最適な場所です。ここに証明書認証の例があり、このブログ投稿に基本認証OWINミドルウェアがあります。前者の例は、基本AuthenticationHandlerクラスの使用法を示しているため、推奨されます。

に関するアドバイスAuthorizationFiltersはほとんど変更されていません。

更新を終了

通常...

DelegatingHandler認証を実行するために使用します...つまり、誰かが誰であるか。これを使用して、スレッドの原則とユーザーコンテキストを設定したり、クレームを追加したりします。ここにも承認ロジックを配置できますが、かなりグローバルな規模です。個人的には、承認には常にAuthorizationFiltersを使用します。

AuthorizationFiltersコントローラとアクションを特定の人に制限するために使用します。これらは、クレーム、プリンシパル、URL、またはhttpリクエストパラメータの情報を使用して権限を推定できる場合に使用されます。デフォルトの承認フィルターを使用して、匿名ユーザーまたはロール(委任ハンドラーなどで設定されている場合)へのアクセスを制限できます。必要に応じて、独自の承認フィルターを実装することもできます。

ActionFiltersメッセージコンテンツを使用して承認を決定する必要がある場合に使用することがあります。たとえば、エンティティのプロパティにアクセスして、アクセスできるかどうかを判断する必要があります(明らかにthis(!)に注意してください)。

ノート:

本文のAuthorizationFiltersコンテンツが読み取られる前にが呼び出されるため、承認を決定するためのメッセージ本文にアクセスできません。これが、認証エラーを発生させるためにActionFilters特に使用される理由です。OnActionExecuting

それで

あなたのシナリオでは、私はDelegatingHandlerあなたのヘッダーを取り、プリンシパルを設定するための簡単なものを置きます。

public class CustomAuthenticationMessageHandler : DelegatingHandler
{


    public CustomAuthenticationMessageHandler ()
    {

    }

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

        return base.SendAsync(request, cancellationToken);
    }

    protected virtual void Authenticate(HttpRequestMessage request)
    {

        var authorisationHeader = request.Headers.Authorization;

        if (authorisationHeader == null)
        {
            return;
        }

        //Ensure you are happy with the header contents then

        {
            var principal = new GenericPrincipal(//new Identity , //Roles);
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;
        }

    }
}

次に、を使用AuthorizationFiltersしてアクセスを制限します。

    [Authorize]
    public string Get()
    {

    }

    [Authorize(Roles = "Admin")]
    public string GetAdminOnly()
    {

    }

グローバル認証を登録するには

config.MessageHandlers.Add(new CustomAuthenticationMessageHandler());

これは、すべてのリクエストでプリンシパルがnullまたは有効なIDに設定されることを意味します。承認を処理しません。つまり、コントローラーやアクションへのアクセスを拒否しません。

リソースの保護を開始するには

保護されたコントローラーとアクションを、標準またはカスタムの[承認]属性でターゲットにします。またはグローバルに登録します。

config.Filters.Add(new AuthorizeAttribute());

また、属性を使用してセキュリティで保護しない必要があるコントローラーとアクションのみをホワイトリストに登録し [AllowAnonymous]ます。

一部のルートでのみ認証が必要な場合

次にDelegatingHandler、少し変更InnerHandlerして、を正しいコントローラーにルーティングするように設定できます。

public CustomAuthenticationMessageHandler(HttpConfiguration configuration)
{
       InnerHandler = new HttpRoutingDispatcher(configuration);
}

そして、次のようにルートでこのハンドラーを指定できます。

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "myurl",
            defaults: new {},
            constraints: new {},
            handler: new CustomAuthenticationHandler(config)
            );
于 2013-02-14T10:42:55.350 に答える