1

この質問は、ASP.NET MVC のアクセス制御に関するこの SO の質問に触発されています。ここでは、受け入れられた答えを具体的な解決策にしようとしています。

答えはFileSystemSecurity、アクセス許可を管理するためのインスピレーションとしての使用について言及しています。ここでは、Flags 属性を持つ列挙型も使用して、すべてのオブジェクトの ACL を定義しています。さらに、オブジェクトの各メンバーは SQL 内の列に格納されます。単純化された Linq2SQL、EF、または nHibernate ORM マッピングを想定します。

編集:このアプローチに次の利点/根拠を追加しました

このセキュリティ モデルは、ファイル レベルのアクセス許可を管理する .NET アプローチであるFileSystemRightsに触発されました。

私がこのアプローチを気に入っている主な理由の 1 つは、すべての個々の ACL を OR で結合することにより、すべてのアクセス許可の概要を簡単に作成できることです。また、継承されたアクセス許可を削除するために DENY ACL を追加できることも気に入っています。

List<myObject> PermissionsList  = GetACLForObject(ItemID, UserID);
foreach (var acl in PermissionsList)
{
   // The following enum has the [FlagsAttribute] applied so the .ToString() is pretty 
   PermissionWithFlagsEnum sampleForSO = (PermissionWithFlagsEnum )acl.Permission;

   Console.Writeline ("Setting " + sampleForSO.ToString() + " permission for group: " + acl.ACLName);

   ResultingPermission = resultPermission |  acl.Permission ; 
}
public int ResultingPermission {get;set;}

/編集終了

enum次に、権限の低いユーザーと権限の高いユーザーの の数値を比較できることに気付きましたenum

この定義により、バックエンドで列挙型を解析する必要なく、SQL データベース内のユーザーをすばやく簡単に識別できるようになると考えています。( で権限のないユーザーを見つけますselect users from permissions where security < DBAceessRights.DetailRead)

フラグを定義した方法は次のとおりです(最小値には最小の権限があります)

[Flags]
public enum DBAccessRights
{
    DenyAll  =1 << 1,

    WikiMode = 1 << 4,

    AppearInListing = 1 << 8,

    DetailRead = 1 << 12,

    CreateNew = 1 << 18,

    DetailEdit = 1 << 22,

    DeleteChild = 1 << 26,

    DeleteThis = 1 << 30,

    EditPermissions = 1 << 31,

}

ユーザー ID をオブジェクト固有の ACE に結合する権限テーブルがあります。これにより、特定の行での同時更新の必要性が減少します。 ここに画像の説明を入力

質問

  • これは良い考えですか?

  • 誰かが以前にそれをやったことがありますか (これよりも優れています)? (編集:ここで受け入れられた回答です

  • これがアクセス許可を実装する標準的な方法である場合、それは何と呼ばれますか?

4

2 に答える 2

4

いいえと思います。

  1. bigint必要な特権は 32 (または を使用する場合は 64) 以下であると想定しています。私には恣意的な制限のように聞こえます。データベース内の に移動すると、varbinaryこれを克服できますが、列挙型がクリークに上がっています ( で列挙型を作成できませんbyte[])! また、数値比較を行うことはできません。

  2. あなたは、特権0x1が常に論理的に以下であると0x2想定しています0x80。それは私の経験ではめったにありません。より一般的には、特権は互いにまったく独立しています (つまり、「ユーザーの追加」特権を持つことは、「画像のアップロード」特権とは何の関係もありません。ユーザーの 1 つのグループ (管理者) は前者を持ち、他のグループ (コンテンツ発行者) は前者を持ちます)。これは、数値比較が最初に考えたほど役に立たないことを意味します。

  3. あなたが行っていることはパフォーマンス上の利点をもたらすかもしれませんが、まだパフォーマンスの問題があることを示していません! 私の特権システムのほとんどは、各特権を付与または拒否するために、ユーザーごとに 1 つのデータベース レコードで動作します。100 件のレコードを取得しても、データベースには負担がかかりません。ビットマスクを使用するよりも、リクエスト間で各ユーザーのアクセス許可を単純にキャッシュする方がよいでしょう。

  4. 更新のパフォーマンスについて: とにかくユーザー権限はどのくらいの頻度で変更されますか? システムが整ったら、私の経験ではかなり静的になる傾向があります。

大量のデータを小さなスペースに詰め込もうとするときに、ビットマスクが最も役立つことがわかりました。しかし、最終的に 64 個を超えると、私のポイント 1 が戻ってきて噛みつくことがよくあります。

ユーザーアクションの統計を記録するときにこの手法を使用したことに注意してください(ユーザーが検索で見つけたアイテム、表示したエンティティなどを追跡します)。私の理由は純粋に、データベースのレコード長が固定され、小さいことを確認して、挿入が高速であることを確認することでした。そして、私は数値比較を行っていませんでした。int(そして、公平を期すために、1 つの列と複数の列に違いがあるかどうかをテストしたことはありませんbit)。

EDIT 基本的な代替手段 (私が使用しています): ユーザーと特権の間の M:N 関係 (私はそれらを権利と呼びます)。

ユーザーから権限への DB ダイアグラム

(私のユーザーのミッキーマウスの耳について申し訳ありません!)

にレコードが存在するUserRightことは、そのユーザーに権限が付与されていることを示します。不在は権利がないことを示します。このクエリは、ユーザーに割り当てられたすべての権利を提供します。

SELECT [dbo].[User].Username, [dbo].[Right].Id, [dbo].[Right].Name
FROM [dbo].[Right]
INNER JOIN [dbo].[UserRight] ON [dbo].[Right].Id = [dbo].[UserRight].RightId
INNER JOIN [dbo].[User] ON [dbo].[User].Id = [dbo].[UserRight].UserId
WHERE [dbo].[User].Id = @pUserId

次に、ユーザーが権利を持っていることをアサートするコードで:

var grantedRights = RunTheAboveQuery(currentUser.Id);
if (grantedRights.Any(r => r.Id == requiredRight))
    // User has the right.
else
    // User does not have the right. 

明らかに、これをスケーリングして、ユーザーが 1 つのクエリで複数の権限を持っていることを確認できます。

これは、システムがサポートする特権の数を人為的に制限するものではありません。また、特権間の関係を想定していません (したがって、数値比較を行うことはできません。すべてはIEnumerable<Right>私のシステムで行われます)。そして、ビットマスクが本当に好きならDictionary<User, BitArray>、キャッシュに を作成できます!

Roleまた、ユーザーに権利の論理グループを提供するの概念もあります。これは単なる別の M:N テーブルです。それは読者のための演習です!

于 2011-11-02T22:19:16.713 に答える
1

一般に、1つのフィールドに複数の値(フラグ)を入れることは悪い考えです。

このデータの監査を計画している場合、更新ごとに変更されたフラグを効率的に把握するのは難しいため、非常に悪い考えです。

監査を行わなくても発生する可能性のある問題

  • 比較の前にビット単位の操作を実行する必要があるため、多くの単純なクエリ(DeleteThis認証を使用するユーザー)はSARG可能ではありません

  • また、はDetailReadより大きいが、DetailReadがオンになっていないselect users from permissions where security < DBAceessRights.DetailReadため、正しい結果が返され ない場合があります。AppearInListing & CreateNewだからあなたがあなたに望んでいた利益は得られないかもしれません

  • 1つの「論理値」を変更すると実際にはすべての値が変更されるため、同時実行性(ACLへの複数のライター)の管理はより困難です。

于 2011-11-02T21:12:32.427 に答える