回答:
ASP.NET MVCコンテキストで、クレームベースのアクセス制御をどのように活用できるかを示します。
ロールベースの認証を使用しているときに、顧客を作成するアクションがあり、「Sale」ロールの人々がそれを実行できるようにしたい場合は、次のようなコードを記述します。
[Authorize(Roles="Sale")]
public ActionResult CreateCustomer()
{
return View();
}
後で、「マーケティング」の役割を持つ人々が顧客を作成できるはずであることに気づきました。次に、そのようにアクションメソッドを更新します。
[Authorize(Roles = "Sale", "Marketing")]
public ActionResult CreateCustomer()
{
return View();
}
これで、一部のマーケティング担当者はCustomerを作成できないようにする必要がありますが、マーケティング担当者に別の役割を割り当てることはできません。したがって、すべてのマーケティング担当者が顧客を作成できるようにする必要があります。
別の問題を発見しました。マーケティング担当者が顧客を作成できるようにする必要があると判断した場合は常に、MVCアクションメソッドのすべてのAuthorize属性を更新し、アプリケーションをコンパイルして、テストしてデプロイする必要があります。数日後、マーケティングではなく、他のロールがタスクを実行できるようにする必要があると判断したため、コードベースを検索し、Authorize属性からすべての「Marketing」を削除し、Authorize属性に新しいロール名を追加します...健康的なソリューション。その時点で、アクセス許可ベースのアクセス制御の必要性に気付くでしょう。
権限ベースのアクセス制御は、さまざまな権限をさまざまなユーザーに割り当て、ユーザーが実行時にコードからアクションを実行する権限を持っているかどうかを確認する方法です。さまざまなユーザーにさまざまな権限を割り当てた後、ユーザーに「Facebookユーザー」、「長時間ユーザー」などのプロパティがある場合、一部のユーザーにコードの実行を許可する必要があることに気付きました。例を挙げましょう。ユーザーがFacebookを使用してログインしている場合に、特定のページへのアクセスを許可するとします。次に、そのユーザーに「Facebook」の権限を作成しますか?いいえ、「Facebook」は許可のようには聞こえません。それはありますか?むしろそれは主張のように聞こえます。同時に、パーミッションもクレームのように聞こえます!! したがって、クレームをチェックしてアクセスを許可することをお勧めします。
ここで、クレームベースのアクセス制御の具体例に戻りましょう。
次のような一連のクレームを定義できます。
「CanCreateCustomer」、「CanDeleteCustomer」、「CanEditCustomer」..など
これで、アクションメソッドを次のように装飾できます。
[ClaimAuthorize(Permission="CanCreateCustomer")]
public ActionResult CreateCustomer()
{
return View();
}
(注意してください、[ClaimAuthorize(Permission = "CanCreateCustomer")]はMVCクラスライブラリに組み込まれていない可能性があります。例として示しているだけです。このようなAttributeクラス定義を持つクラスライブラリを使用できます)
これで、CreateCustomerアクションメソッドには常に 'CanCreateCustomer'のアクセス許可が必要であり、変更されることはほとんどないか、ほとんど変更されないことがわかります。したがって、データベースで、権限(クレーム)とユーザーと権限の関係のテーブルを作成します。あなたの管理者パネルから、あなたは何をすることができる各ユーザーのための許可(主張)を設定することができます。「CanCreateCustomer」権限(クレーム)を好きな人に割り当てることができます。許可されたユーザーのみが顧客を作成でき、許可されたユーザーは顧客のみを作成でき、それ以外は何も作成できません(同じユーザーに他の権限を割り当てない限り)。
このセキュリティモデルは、クリーンなコードプラクティスを提供します。さらに、アクションメソッドを作成するとき、誰がこのメソッドを使用できるかを考える必要はありません。むしろ、このメソッドを使用している人はだれでも、管理者から与えられた適切なアクセス権(クレーム)を持つことを常に保証できます。次に、管理者は誰が何をできるようにするかを決定できます。あなたは開発者ではありません。これが、ビジネスロジックがセキュリティロジックから分離される方法です。
誰かがサインインするときはいつでも、アプリケーションはそのユーザーが利用できる権限をチェックし、その権限(クレーム)セットは現在ログインしているユーザーの追加プロパティとして利用できます(通常、クレームセットはログインしたユーザーのCookieとして保存されます)。そのため、常にデータベースから設定された権限を確認する必要はありません。つまり、ロールベースのアクセスではなくクレームベースのアクセスを適用すると、アプリケーションのセキュリティロジックをより詳細に制御できます。実際、ロールもクレームと見なすことができます。
アプリケーションが、お客様と管理者の2つの役割しかない非常に小さなアプリケーションであり、お客様がアプリケーションで意図されている以外のことを実行できる可能性がない場合、おそらく、役割ベースアクセス制御は目的を果たしますが、アプリケーションが成長するにつれて、ある時点でクレームベースのアクセス制御の必要性を感じ始めます。
CanCreateCustomer, CanViewAdCampaigns
私はこれまで何度もセキュリティモデルを実装しており、これらの概念にも頭を抱える必要がありました。これを何度も行ったので、これらの概念について私の理解を示します。
役割とは
役割= ユーザーと権限の結合。
一方、役割は権限のコレクションです。これをアクセス許可プロファイルと呼びます。ロールを定義するときは、基本的に一連の権限をそのロールに追加するので、その意味でロールは権限プロファイルです。
一方、ロールはユーザーのコレクションでもあります。BobとAliceをロール「マネージャー」に追加すると、「マネージャー」には、グループのような2人のユーザーのコレクションが含まれるようになります。
真実は、ロールは、ユーザーのコレクションとパーミッションのコレクションの両方であるということです。これは視覚的にはベン図として見ることができます。
グループとは
グループ=ユーザーのコレクション
「グループ」は、厳密にはユーザーのコレクションです。グループとロールの違いは、ロールにも権限のコレクションがありますが、グループにはユーザーのコレクションしかありません。
許可とは
許可=対象者ができること
権限セットとは
権限セット=権限のコレクション
堅牢なRBACシステムでは、権限をユーザーのようにグループ化することもできます。グループはユーザーのみのコレクションですが、権限セットは権限のみのコレクションです。これにより、管理者はロールの権限のコレクション全体を一度に追加できます。
ユーザー、グループ、ロール、およびアクセス許可が一体になる方法
堅牢なRBACシステムでは、ユーザーを個別にロールに追加してユーザーのコレクションをロールに作成するか、グループをロールに追加してユーザーのコレクションをロールに一度に追加できます。どちらの方法でも、役割は、ユーザーのコレクションを個別に追加したり、グループを役割に追加したり、ユーザーとグループの組み合わせを役割に追加したりすることで、ユーザーのコレクションを取得します。パーミッションも同様に考えることができます。
権限をロールに個別に追加して、ロール内に権限のコレクションを作成するか、または権限セットをロールに追加できます。最後に、権限と権限セットの組み合わせをロールに追加できます。どちらの方法でも、ロールは、個別に追加されるか、またはロールにアクセス権セットを追加することにより、アクセス権のコレクションを取得します。
ロールの目的はすべて、ユーザーと権限を結びつけることです。したがって、役割はユーザーと権限のUNIONです。
クレームとは
主張=サブジェクトが「何であるか」
クレームは許可ではありません。以前の回答で指摘したように、クレームは、サブジェクトが「できる」ことではなく、サブジェクトが「ある」ことです。
クレームはロールやアクセス許可に代わるものではなく、承認の決定に使用できる追加情報です。
いつクレームを使用するか
ユーザーをロールに追加できない場合、またはユーザーと権限の関連付けに基づいていない場合に承認の決定を行う必要がある場合、クレームが役立つことがわかりました。これは、Facebookユーザーの例が原因です。Facebookユーザーは、「ロール」に追加された人物ではない可能性があります...それらはFacebookを通じて認証された単なる訪問者です。これはRBACにきちんと適合しませんが、承認を決定するための情報の一部です。
@CodingSoftは以前の回答でナイトクラブのメタファーを使用しましたが、これを拡張したいと思います。その答えでは、運転免許証は、一連のクレームを含む例として使用されました。ここで、生年月日はクレームの1つを表し、DateOfBirthクレームの値は、承認規則に対してテストするために使用されます。運転免許証を発行した政府は、クレームに信憑性を与える機関です。したがって、ナイトクラブのシナリオでは、ドアの警備員がその人の運転免許証を見て、偽のID(つまり、政府発行の有効なIDである必要がある)であるかどうかを調べて、信頼できる機関によって発行されたことを確認します。次に、生年月日(運転免許証の多くの請求の1つ)を調べ、その値を使用して、その人がクラブに入会するのに十分な年齢かどうかを判断します。もしそうなら、
さて、そのベースを念頭に置いて、私はそれをさらに拡張したいと思います。ナイトクラブのある建物に、クラブの従業員だけが入ることができるオフィス、部屋、キッチン、その他のフロア、エレベーター、地下室などが含まれているとします。さらに、特定の従業員は、他の従業員がアクセスできない特定の場所にアクセスできる場合があります。たとえば、マネージャは他の従業員がアクセスできないオフィスフロアにアクセスできる場合があります。この場合、2つの役割があります。マネージャーと従業員。
上記で説明したように、訪問者のパブリックナイトクラブエリアへのアクセスは単一のクレームによって許可されますが、従業員は他の非パブリックの制限された部屋へのロールによるアクセスが必要です。彼らにとって、運転免許は十分ではありません。彼らが必要とするのは、彼らがドアに入るのをスキャンする従業員バッジです。どこかに、最上階へのマネージャーロールアクセスのバッジと他の部屋への従業員ロールアクセスのバッジを付与するRBACシステムがあります。
何らかの理由で特定の部屋をロールによって追加/削除する必要がある場合、これはRBACを使用して実行できますが、申し立てには適していません。
ソフトウェアの権限
アプリケーションにロールをコーディングすることは悪い考えです。これにより、ロールの目的がアプリケーションにハードコードされます。アプリケーションに必要なのは、機能フラグのように機能する権限のみです。機能フラグが構成によってアクセス可能になる場合、アクセス許可は、ユーザーが配置されたすべての役割から収集されたアクセス許可のDISTINCTコレクションによって派生するユーザーセキュリティコンテキストによってアクセス可能になります。これを「有効なアクセス許可」と呼びます。アプリケーションは、メニューます機能/アクションへの可能な権限の。RBACシステムは、これらの権限をロールを介してユーザーに結び付ける役割を果たします。このように、ロールのハードコーディングはなく、パーミッションが変更されるのは、それが削除されるか、新しいパーミッションが追加されるときだけです。パーミッションがソフトウェアに追加されたら、決して変更しないでください。必要な場合(つまり、新しいバージョンで機能が廃止された場合)にのみ削除し、新しい機能のみを追加できます。
最後に一言。
グラントvsデニー
堅牢なRBACシステム、さらにはCBACシステムでさえ、許可と拒否を区別する必要があります。
ロールに権限を追加するには、GRANTまたはDENYが必要です。権限をチェックすると、すべての付与された権限が有効な権限のユーザーリストに追加されます。その後、すべてが完了した後、拒否された権限のリストにより、システムはそれらの権限を有効な権限のリストから削除します。
これにより、管理者はサブジェクトの最終的な権限を「微調整」できます。権限をユーザーに直接追加することもできます。このように、ユーザーをマネージャーロールに追加すると、ユーザーはすべてにアクセスできますが、ユーザーが男性であるため、女性用トイレへのアクセスを拒否したい場合があります。したがって、男性ユーザーをマネージャーロールに追加し、許可をユーザーオブジェクトにDENYで追加して、その女性の部屋へのアクセスのみを削除します。
実際、これはクレームの良い候補になります。ユーザーが「gender = male」というクレームを持っている場合、マネージャーロールになっていると、すべての部屋へのアクセス権が付与されますが、女性用トイレには性別=女性のクレーム、男性用化粧室には性別=男性のクレームが必要です。このようにすると、クレームの施行が単一の承認ルールですべての人に対応するため、男性ユーザーにDENY権限を構成する必要がなくなります。ただし、どちらの方法でも可能です。
ポイントは、DENIAL of Permissionsを使用すると、例外を実装できるため、ロールの管理が容易になることです。
以下は、RBACモデルを示す、かなり前に作成した図です。申し立てのグラフィックはありませんが、どこにいてもユーザーに関連付けられている単なる属性であると想像できます。また、図にはグループが表示されていません(いつか更新する必要があります)。
これがお役に立てば幸いです。
2019年4月7日に更新 @ブレント(ありがとう)からのフィードバックに基づいて...以前の回答への不要な参照を削除し、@ CodingSoftが提供する「ナイトクラブ」メタファーの元の基礎を説明し、他の答えを読む。
私はエムランの答えに完全に同意しません
[Authorize(Roles="Sale")]
世間知らず
問題はどのように
[Authorize(Roles="CustomerCreator")]
とは違う
[ClaimAuthorize(Permission="CanCreateCustomer")]
両方が同等に良い場合、なぜクレームが必要ですか?
私は思う
上記の例のコンテキストでは、「CustomerCreator」は「Asp.NETroleProvider」によって提供されるタイプ「ロール」のクレームであると言えます
クレームの追加例。
「AAA」は、「MYExamSite.com」によって提供されるタイプ「MYExamSite.Score」のクレームです
「ゴールド」は、「MYGYMApp」によって提供されるタイプ「MYGYM.Membershiptype」の要求です
受け入れられた回答は、ロールを鈍いオブジェクトとして位置付け、クレームを柔軟なツールとして位置付けるように見えますが、それ以外はほとんど同じに見えます。残念ながら、この位置付けはクレームの概念に害を及ぼし、根本的にその目的のわずかな誤解を反映している可能性があります。
ロールは存在し、暗黙のスコープ内でのみ意味があります。通常、これはアプリケーションまたは組織のスコープ(つまり、Role = Administrator)です。一方、クレームは誰でも「行う」ことができます。たとえば、Google認証では、ユーザーの「メール」を含むクレームを生成し、そのメールをIDに添付する場合があります。Googleが申し立てを行うと、アプリケーションはその申し立てを理解して受け入れるかどうかを選択します。その後、アプリケーション自体が、「ASP.NET MVC Core Identityと同様に」「authenticationmethod」と呼ばれるクレームを「Google」の値で添付する場合があります。各クレームにはスコープが含まれているため、クレームの意味が外部、ローカル、またはその両方(または必要に応じてさらに細かく)にあるかどうかを識別できます。
重要な点は、すべての要求がIDに明示的に添付され、明示的なスコープが含まれていることです。これらのクレームはもちろん認証に使用できます。ASP.NETMVCはAuthorize属性を介してサポートを提供しますが、クレームの主な目的はそれだけではありません。ローカルスコープの承認とまったく同じ方法で使用できるロールとは区別されません。
したがって、承認の目的でロールまたはクレーム、あるいはその両方を使用することを選択でき、それらのロールおよびクレームがローカルにスコープされている限り、どちらにも固有の利点または欠点はありません。ただし、たとえば、承認が外部のIDクレームに依存している場合、役割は不十分になります。外部クレームを受け入れ、それをローカルスコープの役割に変換する必要があります。これには必ずしも問題はありませんが、間接層が導入され、コンテキストが破棄されます。
より広義には、属性ベースのアクセス制御(ABAC)を検討する必要があります。RBACとABACはどちらも、米国国立標準技術研究所(NIST)によって定義された概念です。一方、CBACは、ABACに非常によく似た、Microsoftによってプッシュされたモデルです。
詳細はこちら:
RBACとCBACの間の基本は次のとおりです。
RBAC:アクションの実行を許可するには、ユーザーに役割を割り当てる必要があります。
CBAC:ユーザーは、承認されるために、アプリケーションによって期待されるように、正しい値を持つクレームを持っている必要があります。クレームベースのアクセス制御は、記述が簡単で、保守が簡単です。
クレームは、アプリケーション(証明書利用者)によって信頼されている発行承認サービス(セキュリティサービストークンSTS)によってアプリケーションに発行されることに加えて
ロールはクレームの1つのタイプにすぎません。同様に、他の多くのクレームタイプが存在する可能性があります。たとえば、ユーザー名はクレームタイプの1つです。
どの方法が最適であるかを決定する前に、最初に認証が何に必要かを分析することが重要です。下記のマイクロソフトのドキュメントによると、「請求は対象が実行できることではありません。たとえば、地元の運転免許機関が発行した運転免許証があるかもしれません。あなたの運転免許証には生年月日が記載されています。この場合クレーム名はDateOfBirthで、クレーム値は生年月日(1970年6月8日など)で、発行者は運転免許機関です。クレームベースの認証は、最も簡単な方法として、クレームの値をチェックし、その値に基づくリソース。たとえば、ナイトクラブへのアクセスが必要な場合、承認プロセスは次のようになります。6 "
この例から、クレームベースの承認で隣接するクラブにアクセスすることは、ナイトクラブで働くスタッフが必要とする承認のタイプとは異なることがわかります。この場合、ナイトクラブのスタッフは、ナイトクラブの訪問者全員がナイトクラブで共通の目的を持っているため、ナイトクラブの訪問者には不要な役割ベースの承認。この状況では、クレームベースの承認がナイトクラブの訪問者に適しています。
ロールベースの承認 https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles 10/14/2016 IDが作成されると、1つ以上のロールに属する場合があります。たとえば、トレイシーは管理者とユーザーの役割に属しているのに対し、スコットはユーザーの役割にしか属していない場合があります。これらのロールが作成および管理される方法は、承認プロセスのバッキングストアによって異なります。ロールは、ClaimsPrincipalクラスのIsInRoleメソッドを通じて開発者に公開されます。
クレームベースの承認 https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims 2016年10月14日IDが作成されると、信頼できる当事者によって発行された1つ以上のクレームが割り当てられる場合があります。クレームは、サブジェクトが何ができるかではなく、サブジェクトが何であるかを表す名前と値のペアです。たとえば、地元の運転免許機関が発行した運転免許証があるとします。運転免許証には生年月日が記載されています。この場合、クレーム名はDateOfBirthで、クレーム値は生年月日、たとえば1970年6月8日、発行者は運転免許機関になります。クレームベースの認証は、最も単純な場合、クレームの値をチェックし、その値に基づいてリソースへのアクセスを許可します。たとえば、ナイトクラブへのアクセスが必要な場合、承認プロセスは次のようになります。
ドアのセキュリティ担当者は、アクセスを許可する前に、あなたの生年月日主張の価値と、発行者(運転免許機関)を信頼しているかどうかを評価します。
IDには、複数の値を持つ複数のクレームを含めることができ、同じタイプの複数のクレームを含めることができます。
クレーム方式でロールを管理することもできます。
ビジネスロールを反映する承認ロールを作成する代わりに、CreateCustomer、EditCustomer、DeleteCustomerなどのアクションロールを反映するロールを作成します。必要に応じてメソッドに注釈を付けます。
特にロールリストが大きくなるにつれて、個人をアクションロールのセットにマップすることは簡単なことではありません。したがって、ビジネスロールをより詳細なレベルで管理し(たとえば、セールス、マーケティング)、ビジネスロールを必要なアクションロールにマップする必要があります。つまり、ユーザーをビジネスロールに追加し、既存の承認テーブルで必要な(アクション)ロールにユーザーをマッピングします。
ビジネスロールをオーバーライドして、人物をアクションロールに直接追加することもできます。
すでに機能しているものの上に構築するため、既存の承認プロセスを取り消すことはありません。このアプローチを実装するには、ほんの数個のテーブルが必要です
この質問はデータベースの見込み客から答えられると思います。この埋め込みに関係するテーブルに気づいたら、次のようになります。
このテーブルの使用法は、特定のニーズに合わせて、ユーザー/アプリケーションのライフタイムのある瞬間に微調整することができます。
「購買担当者」(PM)の初期段階を考えると、3つのアプローチが考えられます。
アプリケーションは、AspNetUserRolesに1行を入力して、「PM」の購入権を付与します。任意の金額の注文書を発行するには、ユーザーは「PM」ロールのみが必要です。
アプリケーションは、AspNetUserRolesに1行を入力して 'PM'に購入する権利を付与し、AspNetUserClaimsにTYPE 'Purchasing Amount'タイプのクレームと "<1000"値を入力して、金額制限を設定します。注文書を発行するには、ユーザーは「PM」を持っている必要があり、注文金額はクレームタイプ「購入金額」のクレーム値未満である必要があります。
アプリケーションはAspNetUserClaimsにTYPE 'Purchasing Amount'タイプのクレームと "<1000"値を入力します。金額がこのユーザーのクレームタイプ「購入金額」のクレーム値未満である場合、すべてのユーザーが注文を発行できます。
お気づきのように、ロールベースは、システム管理の観点からアプリケーションユーザーのライフを簡素化する厳格な権限の粗い粒度です。ただし、ビジネス要件の観点からは、ユーザーの能力が制限されます。一方、クレームベースは、各ユーザーに割り当てる必要がある非常に細かい権利です。クレームベースはビジネスにも限界を押し上げますが、システム管理を非常に複雑にします。
役割ベースのアクセス制御(RBAC)
あなたの組織では、次の役割を持っている可能性があります
従業員
マネージャー
人事
ログインしているユーザーが属しているロールに応じて、アプリケーション内の特定のリソースへのアクセスを許可する場合と許可しない場合があります。承認チェックを行うためにロールを使用しているため、これは一般にロールベースアクセスコントロール(RBAC)またはロールベース承認と呼ばれます。
ASP.NET Coreでロールベースの承認を実装するには、Rolesパラメーターと共にAuthorize属性を使用します。
[Authorize(Roles = "Admin")]
public class AdministrationController : Controller
{
}
クレームベースのアクセス制御(CBAC)
クレームとは? クレームは名前と値のペアです。これは実際にはユーザーに関する情報であり、ユーザーが実行できることと実行できないことではありません。たとえば、ユーザー名、メール、年齢、性別などはすべて申し立てです。アプリケーションの承認チェックにこれらのクレームをどのように使用するかは、アプリケーションのビジネス要件と承認要件次第です。
たとえば、従業員ポータルを構築している場合、性別の主張の値が女性であれば、ログインしているユーザーが産休を申請できるようにすることができます。同様に、eコマースアプリケーションを作成している場合、年齢のクレーム値が18以上の場合、ログインしているユーザーが注文を送信できるようにすることができます。
クレームはポリシーに基づいています。ポリシーを作成し、そのポリシーに1つ以上のクレームを含めます。次に、このポリシーをAuthorize属性のpolicyパラメーターと共に使用して、クレームベースの承認を実装します。
[Authorize(Policy = "DeleteRolePolicy")]
public async Task<IActionResult> DeleteRole(string id)
{
}