役割ベースのアクセス許可ベースのアクセス制御


45

私は、アクセス制御(認可)に関して、ロールとパーミッションの固有のトレードオフを理解しようとしています。

与えられたものから始めましょう:私たちのシステムでは、パーミッションはきめ細かいアクセス単位です(「リソースXの編集」、「ダッシュボードページへのアクセス」など)。役割は 1+権限のコレクションになります。ユーザーは 1+役割を持つことができます。これらの関係(ユーザー、ロール、権限)はすべてデータベースに保存され、必要に応じてその場で変更できます。

私の懸念:

(1)アクセス制御のためにロールをチェックすることの「悪い」ところは何ですか?代わりにアクセス許可を確認することでどのような利点が得られますか?言い換えると、これらの2つのスニペットの違いは次のとおりです。

if(SecurityUtils.hasRole(user)) {
    // Grant them access to a feature
}

// vs.
if(SecurityUtils.hasPermission(user)) {
    // Grant them access to a feature
}

そして:

(2)このシナリオでは、ロールはどのような有用な価値を提供しますか?1つ以上のアクセス許可をユーザーに直接割り当てることはできませんか?ロールはどのよう抽象化の具体的な価値を提供しますか(特定の例を挙げられますか)?


2
いくつかのポイント:(1)1人のユーザーが複数のロールを持っている可能性があります、(2)ACL(アクセス制御リスト)を調べたい場合があります。「ダッシュボードページへのアクセス」をダッシュ​​ボードページのサブセットのみに許可したい場合があります(複数ある場合)。
マチューM.

回答:


63

(1)アクセス制御のためにロールをチェックすることの「悪い」ところは何ですか?代わりにアクセス許可を確認することでどのような利点が得られますか?

チェックの時点で、呼び出しコードは「ユーザーXにアクションYを実行する許可があるを知るだけで済みます
呼び出し元のコードは、ロールとアクセス許可の関係を気にせず、認識すべきではありません。

承認レイヤーは、通常、ユーザーのロールにこの権限があるかどうかを確認することにより、ユーザーにこの権限があるかどうかを確認します。これにより、呼び出しコードを更新せずに承認ロジックを変更できます。

呼び出しサイトでロールを直接チェックすると、ロール⇄許可関係を暗黙的に形成し、呼び出しロジックに承認ロジックを挿入し、懸念の分離に違反します。

後でロールにfooアクセス許可がないことを決定したbaz場合は、ユーザーがであるかどうかを確認するすべてのコードを変更する必要がありfooます。

(2)このシナリオでは、ロールはどのような有用な価値を提供しますか?1つ以上のアクセス許可をユーザーに直接割り当てることはできませんか?ロールはどのような抽象化の具体的な価値を提供しますか(誰か特定の例を挙げられますか)?

ロールは、名前付きのアクセス許可のコレクションを概念的に表します。

ユーザーが特定の設定を編集できる新しい機能を追加するとします。この機能は、管理者のみが使用できる必要があります。

ユーザーごとに権限を格納している場合は、あなたが何らかの形で知って、データベース内のすべてのユーザーが管理者である見つける必要があるでしょう(あなたは、ユーザーのロール情報を格納していない場合、どのようにしても、ユーザーが管理者である知っているだろう?) 、およびAPPEND許可のリストへのこの許可。

ロールを使用する場合は、ロールに権限を追加するだけで済みますAdministrator。これは、実行しやすく、スペース効率が高く、ミスが少ないです。


あれ?認証層は、ユーザーがあることを主張する人彼であることを確認します。そのようなユーザーがアクセスできる機能/データをチェックするレイヤーは、承認レイヤーです
-SJuan76

4
これはすべてのプログラマーにとって必須の読み物です。優れた。
コスタKontos

2
シンプル、簡潔、そして要点-どこかで本の章全体を打ちます。ありがとう。
ダンニッセンバウム

2
明確にするためにコメントします(間違っている場合は修正してください):機能authorization layer定義を単純に持っている(つまり)user->hasPermission(SOME_PERMISSION)最初にユーザーのロールを内部的にチェックしてから、指定された許可。例えば、the calling code特定のページがユーザのために表示されると呼ぶだろうかどうかを確認するためにチェックされるかもしれないuser->hasPermission(VIEW_GIVEN_PAGE)、とauthorization layerから構成定義hasPermission上記のような役割を確認機能。
ダンニッセンバウム

1
@DanNissenbaumええ、あなたはそれを正しかったように聞こえますが、ユーザーの役割がこの承認を持っているかどうかを確認するだけで簡単です。それ以上の可能性もあります。たとえば、ユーザーを一時的に停止するオプションがあり、その場合hasPermissionはを確認できusersRole.HasPermission(VIEW_GIVEN_PAGE) && !user.Suspendedます。重要なのは、すべてを1つの場所で行い、消費(呼び出し)コードではないということです。
ロテム

18

最初の質問に対する回答として、ユーザーが特定のアクセス許可ではなくロールを持っていることを確認する際の最大の問題は、アクセス許可が複数のロールによって保持されることです。この例として、開発者は会社のイントラネット上の開発者ポータルを表示するためのアクセス権を持っている場合がありますが、これはおそらくマネージャーによって保持されている許可です。ユーザーが開発者ポータルにアクセスしようとすると、次のようなチェックが行われます。

if(SecurityUtils.hasRole(developer)) {
    // Grant them access to a feature
} else if(SecurityUtils.hasRole(manager)) {
    // Grant them access to a feature
} else if...

switchあなたの選択した言語での声明は良いでしょうが、それでもまだ特に整頓されていません)

権限がより一般的または広く保持されているほど、誰かが特定のシステムにアクセスできることを確認するために確認する必要があるユーザーロールが増えます。これは、ロールのアクセス許可を変更するたびに、これを反映するようにチェックを変更する必要があるという問題にもつながります。大規模なシステムでは、これはすぐに非常に扱いにくくなります。

たとえば、ユーザーが開発者ポータルへのアクセスを許可するアクセス許可を持っていることを確認するだけであれば、ユーザーがどのロールを保持しているかに関係なく、アクセスが許可されます。

2番目の質問に答えるために、あなたが役割を持っている理由は、権限の「パッケージ」を簡単に変更および配布できるためです。数百のロールと数千の権限を持つシステムを使用している場合、新しいユーザー(たとえば、新しいHRマネージャー)を追加するには、他のHRマネージャーが保持しているすべての権限を通過する必要があります。これは退屈なだけでなく、手動で行うと間違いが発生しやすくなります。これを単に「HRマネージャー」ロールをユーザーのプロファイルに追加すると、そのロールを持つ他のすべてのユーザーと同じアクセス権が付与されます。

単に既存のユーザーのクローンを作成できると主張することができます(システムがこれをサポートしている場合)が、これはその時点でユーザーに正しい権限を付与しますが、将来すべてのユーザーの権限を追加または削除しようとすると難しい。このシナリオの例としては、過去に人事スタッフも給与を担当していたが、後に会社が給与を処理するためにスタッフを雇用できるほど大きくなった場合が考えられます。これは、人事部門が給与システムにアクセスする必要がなくなり、許可を削除できることを意味します。HRのメンバーが10人いる場合は、手動で確認し、ユーザーエラーが発生する可能性のある正しい権限を削除する必要があります。これに関する他の問題は、単にスケールしないことです。特定の役割でより多くのユーザーを獲得すると、役割の変更がはるかに困難になります。これをロールの使用と比較してください。ロールを使用すると、問題の包括的なロールを変更するだけで、そのロールを保持するすべてのユーザーに反映されるアクセス許可を削除できます。


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