web-dev-qa-db-ja.com

Asp.net WebApiのカスタム認証-何が混乱していますか?

WebApiでの承認について、いくつかのリソース(書籍およびSO回答)から読んでいます。

特定のユーザーのみにアクセスを許可するカスタム属性を追加するとします。

ケース#1

私はこのアプローチを見ましたoverridingOnAuthorization、何かが間違っている場合に応答を設定します

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 public override void OnAuthorization(HttpActionContext actionContext)
  {
   if ( /*check if user OK or not*/)
   {
     actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
   }
  }
}

ケース#2

しかし、OnAuthorizationをオーバーライドするが、baseを呼び出すことで、同様の例を見たことがあります:

public override void OnAuthorization(HttpActionContext actionContext) 
{ 
  base.OnAuthorization(actionContext);

    // If not authorized at all, don't bother

    if (actionContext.Response == null)  
     {
      //...
     }
}

次に、HttpActionContext.Responseが設定されているかどうかを確認します。設定されていない場合、リクエストは承認され、ユーザーは大丈夫であることを意味します

ケース#3

しかし、IsAuthorizedをオーバーライドするこのアプローチも見ました:

public class AllowOnlyCertainUsers : AuthorizeAttribute
{
 protected override bool IsAuthorized(HttpActionContext context)
  {
   if ( /*check if user OK or not*/)
   {
    return true;// or false
   }
  }
}

ケース#4

そして、同様の例を見ましたが、base.IsAuthorized(context)を呼び出しています:

protected override bool IsAuthorized(HttpActionContext context)
{
 if (something1 && something2 && base.IsAuthorized(context)) //??
 return true;
 return false;
}

もう1つ

そして最後に、ドミニクは ここ を言った:

OnAuthorizationをオーバーライドしないでください-[AllowAnonymous]の処理が欠落しているためです。

質問

  • 1)IsAuthorizedまたはOnAuthorizationのどのメソッドを使用する必要がありますか? (またはどちらを使用するか)

  • 2)base.IsAuthorized or base.OnAuthorization`をいつ呼び出すべきですか?

  • 3)これは彼らがどのように構築したか?応答がnullの場合、すべてがOKですか? (ケース#2)

NB

すでにAuthorizeAttributeを継承しているAuthorizationFilterAttributeのみを使用している(使用したい)ことに注意してください

どうして ?

私が最初の段階にいるので: http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

enter image description here

とにかく、Authorize属性を拡張することで問い合わせています。

103
Royi Namir

使用すべきメソッドはIsAuthorizedとOnAuthorizationのどちらですか? (またはどちらを使用するか)

認証ロジックが確立されたIDとロールに依存しない場合は、AuthorizationFilterAttributeを拡張します。ユーザー関連の許可の場合、AuthorizeAttributeを拡張して使用します。前者の場合、OnAuthorizationをオーバーライドします。後者の場合、IsAuthorizedをオーバーライドします。これらの属性のソースコードからわかるように、OnAuthorizationはvirtualとしてマークされ、AuthorizationFilterAttributeから派生した場合にオーバーライドできます。一方、IsAuthorizedメソッドは、AuthorizeAttributeでvirtualとマークされています。これは、意図した使用法への優れた指針であると思います。

base.IsAuthorizedまたはbase.OnAuthorizationをいつ呼び出す必要がありますか?

この質問に対する答えは、OOの一般的な動作にあります。メソッドをオーバーライドする場合、新しい実装を完全に提供するか、親が提供する実装に便乗して動作を強化することができます。たとえば、IsAuthorized(HttpActionContext)の場合を考えます。基本クラスの動作は、フィルターで指定されたものと確立されたIDに対してユーザー/ロールをチェックすることです。すべてを実行したいが、さらに、リクエストヘッダーなどに基づいて何か他のものをチェックしたい場合。その場合、このようなオーバーライドを提供できます。

protected override bool IsAuthorized(HttpActionContext actionContext)
{
    bool isAuthroized = base.IsAuthorized(actionContext);
    // Here you look at the header and do your additional stuff based on actionContext
    // and store the result in isRequestHeaderOk
    // Then, you can combine the results
    // return isAuthorized && isRequestHeaderOk;
}

申し訳ありませんが、Q3を理解できません。ところで、認証フィルターは長い間存在しており、人々はそれをあらゆる種類のものに使用しますが、時には誤って使用することもあります。

もう一つ。そして最後に、この人が言った:OnAuthorizationをオーバーライドしないでください-[AllowAnonymous]の処理が欠落しているためです。

それを言ったのはアクセス制御の神、ドミニク。明らかにそれは正しいでしょう。 OnAuthorization(以下にコピー)の実装を見ると、

public override void OnAuthorization(HttpActionContext actionContext)
{
    if (actionContext == null)
    {
        throw Error.ArgumentNull("actionContext");
    }

    if (SkipAuthorization(actionContext))
    {
        return;
    }

    if (!IsAuthorized(actionContext))
    {
        HandleUnauthorizedRequest(actionContext);
    }
}

SkipAuthorizationの呼び出しは、AllowAnonymousフィルターが適用されること、つまり許可がスキップされることを保証する部分です。このメソッドをオーバーライドすると、その動作が失われます。実際に、ユーザー/ロールに基づいて許可を決定する場合、その時点でAuthorizeAttributeから派生することになります。その時点で残っている正しいオプションのみが、IsAuthorizedをオーバーライドすることであり、既にオーバーライドされているOnAuthorizationではなく、技術的には可能です。

PS。 ASP.NET Web APIには、認証フィルターと呼ばれる別のフィルターがあります。アイデアは、名前が示すように、認証用のそれを使用し、承認用の承認フィルターを使用することです。ただし、この境界が不正確である多くの例があります。多くの認証フィルターの例は、何らかの認証を行います。とにかく、時間があり、もう少し理解したい場合は、このMSDN 記事 をご覧ください。免責事項:それは私によって書かれました。

90
Badri

わかりました。私の提案は、Web APIを保護するためにOAuth bearerトークンを使用し、トークンを発行したときにユーザーのクレームとしてallowedTimeを設定していると仮定して、以下を実行することです トークンベースの認証はこちら の詳細を読むことができます

  1. AuthorizationFilterAttributeから派生するCustomAuthorizeAttributeを作成します
  2. メソッドOnAuthorizationAsyncをオーバーライドし、以下のサンプルコードを使用します。

     public class CustomAuthorizeAttribute : AuthorizationFilterAttribute
    {
    
        public override Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken)
        {
    
            var principal = actionContext.RequestContext.Principal as ClaimsPrincipal;
    
            if (!principal.Identity.IsAuthenticated)
            {
                return Task.FromResult<object>(null);
            }
    
            var userName = principal.FindFirst(ClaimTypes.Name).Value;
            var userAllowedTime = principal.FindFirst("userAllowedTime").Value;
    
            if (currentTime != userAllowedTime)
            {
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, "Not allowed to access...bla bla");
                return Task.FromResult<object>(null);
            }
    
            //User is Authorized, complete execution
            return Task.FromResult<object>(null);
    
        }
    }
    
  3. ここで、コントローラーでCustomAuthorize属性を使用して、この承認ロジックを使用してコントローラーを保護します。
17
Taiseer Joudeh

ASP.NET v5は完全に新しい認証システムを導入しました。 .NET 5を使用する場合は、Microsoft.AspNet.Authorizationに移行することをお勧めします。

System.Web.Http.AuthorizeSystem.Web.Mvc.Authorizeの両方、およびその他の古い認証の実装を維持することによって引き起こされる混乱をほぼ終わらせます。

アクションタイプ(作成、読み取り、更新、削除)、リソース、ロール、クレーム、ビュー、カスタム要件の非常に優れた抽象化を提供し、上記のいずれかを組み合わせてカスタムハンドラーを構築できます。さらに、これらのハンドラーを組み合わせて使用​​することもできます。

ASP.NET v5では、承認は、単純な宣言型の役割と、承認が要件で表現され、ハンドラーが要件に対するユーザークレームを評価するより豊富なポリシーベースのモデルを提供するようになりました。命令型チェックは、ユーザーがアクセスしようとしているリソースのユーザーIDとプロパティの両方を評価する単純なポリシーまたはポリシーに基づくことができます。

3