質問

さまざまな種類のアクセス許可を提供する必要がある次のようなシナリオによく遭遇します。私は主に SQL Server 2000 で ASP.NET / VB.NET を使用しています。

シナリオ

さまざまなパラメーターを操作できる動的な権限システムを提供したいと考えています。部門または特定の個人にアプリケーションへのアクセスを許可したいとします。そして、成長し続けるアプリケーションが多数あると仮定してください。

私はこれまで、これを行うために知っている次の 2 つの方法のいずれかを選択しました。

  1. パラメーターを適用する方法を決定するために使用される特別な列を備えた単一の許可テーブルを使用します。この例の特別な列は、TypeIDとTypeauxidです。SQLはこのようなものになります。

    SELECT COUNT(PermissionID)
    FROM application_permissions
    WHERE
    (TypeID = 1 AND TypeAuxID = @UserID) OR
    (TypeID = 2 AND TypeAuxID = @DepartmentID)
    AND ApplicationID = 1
    
  2. 許可の種類ごとにマッピングテーブルを使用し、それらをすべて一緒に結合します。

    SELECT COUNT(perm.PermissionID)
    FROM application_permissions perm
    LEFT JOIN application_UserPermissions emp
    ON perm.ApplicationID = emp.ApplicationID
    LEFT JOIN application_DepartmentPermissions dept
    ON perm.ApplicationID = dept.ApplicationID
    WHERE q.SectionID=@SectionID
      AND (emp.UserID=@UserID OR dept.DeptID=@DeptID OR
     (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
    ORDER BY q.QID ASC
    

私の考え

例が理解できることを願っています。私はそれらを一緒に石畳みました。

最初の例の方が作業量は少なくなりますが、どちらも最良の答えとは思えません。これに対処するより良い方法はありますか?

役に立ちましたか?

解決

私もジョン・ダウニーの意見に同意します。

個人的には、フラグ付きのアクセス許可の列挙を使用することがあります。このようにして、列挙型の項目に対して AND、OR、NOT、および XOR のビット単位の演算を使用できます。

"[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}"

次に、ビットごとの AND 演算子を使用して、いくつかの権限を組み合わせることができます。

たとえば、ユーザーがユーザーを表示および編集できる場合、操作のバイナリ結果は 0000 0011 となり、10 進数に変換すると 3 になります。
その後、1 人のユーザーの権限をデータベースの 1 つの列 (この場合は 3 列) に保存できます。

アプリケーション内で必要なのは、ユーザーが特定の権限を持っているかどうかを確認するために別のビット単位の演算 (OR) を行うだけです。

他のヒント

パーミッション システムのコーディングに関して私が通常行う方法は、6 つのテーブルを用意することです。

  • ユーザー - これは非常に簡単で、典型的なユーザー テーブルです。
  • グループ - これはあなたの部門と同義です
  • ロール - これは、一般に人間が判読できる名前と説明も含むすべての権限を含むテーブルです。
  • Users_have_Groups - これは、ユーザーがどのグループに属しているかを示す多対多のテーブルです。
  • Users_have_Roles - 個々のユーザーにどのロールが割り当てられているかを示す別の多対多のテーブル
  • Groups_have_Roles - 各グループがどのような役割を持っているかを示す最終的な多対多のテーブル

ユーザー セッションの開始時に、ディレクトリまたはグループを通じてユーザーに割り当てられたすべてのロールを引き出すロジックを実行します。次に、それらのロールに対してセキュリティ権限としてコーディングします。

先ほども言いましたが、これが私が通常行うことですが、あなたのミレージは異なる場合があります。

John Downey と jdecuyper のソリューションに加えて、ビットフィールドの最後/先頭に「明示的な拒否」ビットも追加しました。これにより、グループ、ロール メンバーシップごとに追加のアクセス許可を実行し、明示的な拒否に基づいてアクセス許可を差し引くことができます。エントリは、権限に関しては NTFS の動作と同様です。

正直なところ、ASP.NET メンバーシップ/ロール機能は、説明したシナリオでは完璧に機能します。独自のテーブル/プロシージャ/クラスを作成することは素晴らしい練習であり、細かい詳細を非常にうまく制御できますが、これを自分で行った後、組み込みの .NET のものを使用する方が良いという結論に達しました。既存のコードの多くはそれを回避するように設計されており、これは非常に優れています。スクラッチから書くのに約 2 週間かかりましたが、.NET ほど堅牢ではありませんでした。非常に多くのくだらないコード (パスワード回復、自動ロックアウト、暗号化、ロール、権限インターフェイス、大量の proc など) をコーディングする必要があるため、その時間を別のことに費やしたほうがよいでしょう。

あなたの質問に答えられなかったらごめんなさい、私は誰かが VB の質問をしたときに C# を学ぶように言う男のようなものです。

私がさまざまなアプリケーションで使用したアプローチは、変更可能な Value プロパティを持つ汎用 PermissionToken クラスを用意することです。次に、要求されたアプリケーションをクエリすると、そのアプリケーションを使用するためにどの PermissionToken が必要かがわかります。

たとえば、配送アプリケーションは次のものが必要であることを通知する場合があります。

new PermissionToken()
{
    Target = PermissionTokenTarget.Application,
    Action = PermissionTokenAction.View,
    Value = "ShippingApp"
};

これは明らかに、作成、編集、削除などに拡張でき、カスタムの Value プロパティにより、アプリケーション、モジュール、またはウィジェットで独自の必要なアクセス許可を定義できます。YMMV ですが、これは私にとって常に効率的な方法であり、うまく拡張できることがわかりました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top