Asp.net WebApiのカスタム認証-混乱


113

WebApiでの承認に関するいくつかのリソース(本とSOの回答)を読んでいます。

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

ケース#1

私は、オーバーライドの このアプローチを見てきました OnAuthorization。これは、何かが間違っている場合に応答を設定します

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

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

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

もう一つ

そして最後にドミニクはここで言っ

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

ご質問

  • 1)どの方法を使用する必要がありますか:IsAuthorizedまたはOnAuthorization?(またはいつ使用するか)

  • 2)base.IsAuthorized orbase.OnAuthorization`はいつ呼び出す必要がありますか?

  • 3)これは彼らがそれをどのように構築したか?応答がnullの場合、すべて問題ありませんか?(ケース#2)

NB

注意してください、私はAuthorizeAttributeすでに継承しているものだけを 使用しています(そして使用したい)AuthorizationFilterAttribute

どうして ?

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

ここに画像の説明を入力してください

とにかくAuthorize属性を拡張して質問します。


Authorize属性をオーバーライドするために何が必要ですか?達成したいユースケースは何ですか?特定のユーザーにアクセスを許可する必要がある場合、このように[Authorize(Users = "Admin")]属性を使用しないのはなぜですか?
Taiseer Joudeh 2014年

1
@TaiseerJoudehたとえば、10:00から12:00の間でユーザーを認証します(構成可能)。プレーンなロールと承認された属性を使用してそれを行うことはできません。独自のロジックを作成する必要があります
Royi Namir '20

回答:


93

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

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

いつ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の記事をご覧ください。免責事項:それは私が書いたものです。


改めて感謝しますが、行間を読んだ場合、IsAuthenticatedはOnAuthirizationによる呼び出しなので、OnAuthorizationをオーバーライドしてbase.OnAuthorizationを呼び出してから、応答を確認してください。
Royi Namir 2014

それがあなたが望むものであれば、あなたは確かにできる。
バドリ

私の3番目の質問では、ベース関数(base.OnAuthorizationなど)を実行した後、それが成功したかどうかを確認する唯一の方法は、Responseプロパティを検査することですか?、psサンプルはあなたの本からの
引用です

はい、通常、私が知る限り、401ステータスコードを探しますが、nullではありません。ところで、OnAuthorization私の本でオーバーライドについて書いた覚えはありません。nullの応答をチェックすることについて書いたことはないと思いますが、cozについて聞いたのはこれが初めてです:)
Badri

はい、私は他の本と混同しました。私は3冊の本を同時に読んでいます。securty(あなたのもの)、実用(あなたのもの)、webapi pro(Tugberk's、Zeitler、Ali)です。あなたが見ることができるように-彼らはそこでそれをしました: i.stack.imgur.com/LNGi4.jpg-彼らはちょうどnullかどうかをチェックしたので、私はnullまたはエラーコードをチェックするべきですか?
Royi Namir 2014

18

OAuthベアラトークンを使用してWeb APIを保護し、トークンを発行したときにユーザーの要求として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属性を使用して、この認証ロジックを使用してコントローラーを保護します。

1
ありがとう。しかし、私は現在、AuthorizeAttributeどちらが継承するかを使用しています。AuthorizationFilterAttributeまた、学習のために、どのメソッドを使用する必要があるか、および応答にコンテンツがあるかどうかについて具体的に尋ねました...
Royi Namir

3

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

System.Web.Http.AuthorizeSystem.Web.Mvc.Authorizeと他の古い認証実装の両方を維持することによって引き起こされる混乱をほぼ解消し ます。

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

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


14
知っておくと良いですが、質問にはまったく答えません。
Zero3
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.