ASP.NET Identityでのロールとクレームのベストプラクティス


94

私はclaimsin の使用にまったくASP.NETIdentity慣れていないので、の使用のベストプラクティスについて知りたいと思いRoles and/or Claimsます。

このすべてを読んだ後、私はまだ次のような質問があります...

Q:ロールを使用しなくなりましたか?
Q:その場合、なぜ役割がまだ提供されているのですか?
Q:クレームのみを使用する必要がありますか?
Q:ロールとクレームを一緒に使用する必要がありますか?

私の最初の考えは、それらを一緒に「使用すべき」であるということです。私ClaimsRoles彼らがサポートするサブカテゴリとして見ています。

例:
役割:会計
クレーム:CanUpdateLedger、CanOnlyReadLedger、CanDeleteFromLedger

Q:それらは相互に排他的であることを意図していますか?
Q:または、クレームのみに進み、クレームを「完全に修飾」する方が良いですか?
Q:では、ここでのベストプラクティスは何ですか?

例:ロールとクレームを一緒に使用する
もちろん、このために独自の属性ロジックを作成する必要があります...

[Authorize(Roles="Accounting")]
[ClaimAuthorize(Permission="CanUpdateLedger")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}

例:申し立てを完全に修飾する

[ClaimAuthorize(Permission="Accounting.Ledger.CanUpdate")]
public ActionResult CreateAsset(Asset entity)
{
    // Do stuff here

    return View();
}

1
それで、私は今同じ問題に直面しています、どのようにそれを解決し、どのようにアプリケーションでパーミッションをサブロールすることができますか?
Loai 2016年

回答:


77

ロールは、同じレベルのセキュリティ特権を共有するユーザーを集めた象徴的なカテゴリです。役割ベースの許可では、最初にユーザーを識別し、次にユーザーが割り当てられている役割を確認し、最後にそれらの役割をリソースへのアクセスが許可されている役割と比較する必要があります。

対照的に、クレームはグループベースではなく、IDベースです。

Microsoftのドキュメントから:

IDが作成されると、信頼できる当事者によって発行された1つ以上のクレームが割り当てられる場合があります。クレームは、サブジェクトが何ができるかではなく、サブジェクトが何であるかを表す名前と値のペアです。

セキュリティチェックは、1つ以上のクレームの値に基づいて、リソースにアクセスする権利を後で決定できます。

両方組み合わせて使用​​することも、1つのタイプを特定の状況で使用し、他のタイプを別の状況で使用することもできます。それは主に他のシステムとの相互運用とあなたの管理戦略に依存します。たとえば、特定のクレームが割り当てられているユーザーを管理するよりも、マネージャーがロールに割り当てられているユーザーのリストを管理する方が簡単な場合があります。クレームは、クライアントにクレームを割り当てることができるRESTfulシナリオで非常に役立ちます。クライアントは、要求ごとにユーザー名とパスワードを渡すのではなく、認証のためにクレームを提示できます。


6
これが完全に正しいとは思いません。申し立ては承認ではなくアイデンティティを示していると思います。彼らに許可されていることは個別に管理されます。つまり、生年月日が18歳以上であることを示すクレームがある可能性があります。このクレームは承認マネージャーに渡され、「18歳以上の場合、リソースXを編集できる」というルールを含めることができます。しかし、クレーム自体は、彼らが何ができるか、またはできないか、またはアクセスできないかを示していません。役割やその他の主張についても同様です。主張はあなたが誰であるかを示し、あなたが何ができるかを決定するために使用されますが、彼らは直接あなたに伝えません
ChrisC '31 / 07/31

@ChrisCのサポートドキュメントは、ASP.NET Coreの Microsoftのクレームベースの承認からのものです。「クレームは、サブジェクトが何を実行できるかではなく、サブジェクトが何であるかを表す名前と値のペアです。」
DrGriff

@DrGriffそのリンクを提供していただきありがとうございます。私はしばらく、私が与えた説明の正確さについて質問してきました。私はそのリンクに基づいて答えを明確にしたと思います。
Claies

29

@Claiesが完全に説明したように、クレームはより説明的であり、深い役割です。私はそれらをあなたの役割IDとして考えます。私はジムIDを持っているので、メンバーロールに属しています。私はキックボクシングのレッスンにも参加しているので、キックボクシングIDの要求があります。私のアプリケーションは、私のメンバーシップの権利に合うように新しい役割の宣言を必要とするでしょう。代わりに、たくさんの新しいメンバーシップタイプではなく、所属する各グループクラスのIDを持っています。そのため、申し立ての方が適しています。

役割よりもクレームを使用することの利点について語る、バリードランスのすばらしい説明ビデオがあります。彼はまた、ロールは下位互換性のためにまだ.NETにあると述べています。このビデオは、クレーム、役割、ポリシー、承認、認証の仕組みについて非常に有益です。

あなたはそれをここで見つけることができます:Barr DorransによるASP.NET Core Authorization


8

何十年にもわたってさまざまな認証および承認技術を使用してきた私の現在のMVCアプリケーションは、次の方法論を使用しています。

クレームはすべての承認に使用されます。ユーザーには1つの役割が割り当てられます(複数の役割が可能ですが、これは必要ありません)。

一般的な方法と同様に、ClaimsAuthorize属性クラスが使用されます。ほとんどのコントローラーアクションはCRUDであるため、コードファーストデータベース生成には、すべてのコントローラーアクションを反復し、読み取り/編集/作成/削除の各コントローラーアクション属性のクレームタイプを作成するルーチンがあります。たとえば、

[ClaimsAuthorize("SomeController", "Edit")]
[HttpPost]

MVCビューで使用するために、基本コントローラークラスはビューバッグアイテムを提示します

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // get user claims
            var user = filterContext.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

            if (user != null)
            {
                // Get all user claims on this controller. In this controler base class, [this] still gets the descendant instance type, hence name
                List<Claim> claims = user.Claims.Where(c => c.Type == this.GetType().Name).ToList();

                // set Viewbag with default authorisations on this controller
                ViewBag.ClaimRead = claims.Any(c => c.Value == "Read");
                ViewBag.ClaimEdit = claims.Any(c => c.Value == "Edit");
                ViewBag.ClaimCreate = claims.Any(c => c.Value == "Create");
                ViewBag.ClaimDelete = claims.Any(c => c.Value == "Delete");
            }

            base.OnActionExecuting(filterContext);
        }

ウェブサイトのメニューやその他のコントローラー以外のアクションについては、他にも申し立てがあります。たとえば、ユーザーが特定の通貨フィールドを表示できるかどうか。

bool UserHasSpecificClaim(string claimType, string claimValue)
{
    // get user claims
    var user = this.HttpContext.User as System.Security.Claims.ClaimsPrincipal;

    if (user != null)
    {
        // Get the specific claim if any
        return user.Claims.Any(c => c.Type == claimType && c.Value == claimValue);
    }

    return false;
}

public bool UserHasTradePricesReadClaim
{
    get
    {
        return UserHasSpecificClaim("TradePrices", "Read");
    }
}

では、役割はどこに収まるのでしょうか?

ロールを(デフォルトの)クレームのセットにリンクするテーブルがあります。ユーザー認証を設定する場合、デフォルトでは、ユーザーに役割のクレームを付与します。各ユーザーは、デフォルトよりも多いまたは少ないクレームを持つことができます。編集を簡単にするために、クレームリストはコントローラーおよびアクション(行)ごとに表示され、他のクレームがリストされます。ボタンは、Javascriptを少し使用してアクションのセットを選択し、クレームの選択に必要な「クリック」を最小限に抑えます。保存すると、ユーザーの要求が削除され、選択した要求がすべて追加されます。Webアプリケーションはクレームを1回だけロードするため、変更を行うと、この静的データ内でリロードを促す必要があります。

したがって、マネージャーは、各ロールにあるクレームと、ユーザーがロールに設定した後にユーザーが持つクレームとそれらのデフォルトクレームを選択できます。システムには少数のユーザーしかないため、このデータの管理は簡単です


3

ロールとクレームの違いを理解するために、ロールの制限に直面する必要があり、クレームがこの問題をどのように解決するかを感じるために、ロールがこの問題を解決できないクレームの力を認識する2つのシナリオを示します。

1-サイトには2つのモジュール(ページ、サービスなど)が必要です。最初のモジュールは子供(18歳未満)、もう1つは大人(18歳以上)のユーザーIDで誕生日を要求します。

各モジュールの承認がこの値に与えられるように、この主張に関するポリシーを作成する必要があります。ユーザーの年齢が18歳を超える場合、この年齢より前ではなく大人のモジュールに行くことができます

ロールはブールデータ型であり、ロールロールにはモルティ値がないか、ロールロールにありません。

2-あなたのサイトにはロールユーザーがいて、コードを変更せずにメンテナンスを行うためにユーザーのアクセスを禁止したくない

クレームでは、真のユーザーがページを表示できない場合に、ロールユーザーにプロパティを承認するUnderConstrainポリシーを作成できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.