「管理者」Webアプリケーションの許可システムを設計する最良の方法を検討しています。アプリケーションには、多くのユーザーがいる可能性が高く、各ユーザーには特定の役割を割り当てることができます。これらのユーザーの一部は、ロール外で特定のタスクを実行することを許可される可能性があります。
これを設計するには、2つの方法が考えられます。1つは、すべてのユーザーの行を含む「permissions」テーブルと、それらのタスクを実行する権限を割り当てるブール列(各タスクに1つ)です。このような:
ユーザーIDユーザーの管理製品の管理プロモーションの管理注文の管理 1 true true true true 2 false true true true 3 false false false true
私が考えたもう1つの方法は、ビットマスクを使用してこれらのユーザー権限を保存することでした。これにより、32ビットの符号付き整数で管理できるタスクの数が31に制限されますが、実際には、ユーザーが実行できる特定のタスクが31を超えることはほとんどありません。この方法では、データベーススキーマがより簡単になり、アクセス制御が必要な新しいタスクを追加するたびにテーブル構造を変更する必要がなくなります。このような:
ユーザーIDのアクセス許可(8ビットマスク)は、テーブルのintです。 1 00001111 2 00000111 3 00000001
ここで人々が一般的に使用するメカニズムは何ですか?その理由は?
ありがとう!
宇宙の意味をエンコードする神秘的なビット列から離れることは、一般的な経験則だと思います。
おそらく不格好ですが、可能なアクセス許可のテーブル、ユーザーのテーブル、およびそれらの間のリンクテーブルを持つことは、これを整理するための最良かつ最も明確な方法です。また、クエリとメンテナンス(特に新しい人にとって)が非常に簡単になります。
permissionテーブルを作成してから、UserPermissionテーブルを作成して関係を保存するのはどうですか?
構造を再度変更する必要はありません。また、必要な数の権限を追加できます。
私はそれを両方の方法で行いました。しかし、ビットマスクはもう使用しません。ユーザーIDまたはグループIDを外部キーとして指定すると、相互参照として使用できる別のテーブルで問題ありません。
UserID | Permission
===================
1 | 1 1 representing manage users
1 | 2 2 being manger products
2 | 3
この方法の方が、後から保守や追加が簡単になります。
また、別のテーブルを使用して、アクセス許可を管理します。
PermissionID | Description
==========================
1 | Manage Users
2 | Manager Products
通常、Usersテーブル、Rolesテーブル、およびUserRolesテーブルがあります。これにより、db構造を変更せずに無制限の数のロールを持つことができ、ユーザーは複数のロールに所属できます。
私はアプリケーションにロールに対してのみ許可するように強制します(ユーザーには許可しません)。ロールテーブルの「id」列がID列ではないことに注意してください。これは、アプリケーションが特定のIDを探す必要があるため、このテーブルに格納されるIDを制御する必要がある場合があるためです。
構造は次のようになります。
create table Users (
id int identity not null,
loginId varchar(30) not null,
firstName varchar(50) not null,
etc...
)
create table Roles (
id int not null,
name varchar(50) not null
)
create table UserRoles (
userId int not null,
roleId int not null
)
ロールプロバイダーの概念を使用して、Webアプリケーションのアクセス許可を抽象化することをお勧めします。バージョン2.0以降、これは.NETで System.Web.Security.RoleProvider として提供されます。
基本的な考え方は、特定のストレージメカニズムではなく、フレームワークに対して権限チェックを記述することにより、既存のフレームワークを活用することです。次に、使用可能なストレージメカニズムを、XMLファイル、データベース、または 承認ストア であるかどうかにかかわらず、Windowsソフトウェア承認マネージャーを使用してプラグインできます(これにより、カスタムアクセス許可を1つの例としてのLDAP-設定にコードは必要ありません。
データベースをストレージメカニズムとして使用する場合、フレームワークが必要とする基になるテーブルの自動作成のために、いくつかのデータベースがサポートされます。これには、Monoでの.NETの実行と、MySQL上でのロールプロバイダーモデルの使用が含まれます。
詳細については、「 ロールプロバイダーの実装 」を参照してください。他の言語/環境にも、この概念を実装するために活用できるライブラリがある可能性があります。検討する価値があります。
[〜#〜] edit [〜#〜]:また、Webアプリケーションがストレージメカニズムにどのように結び付けられるかの構成も指摘する必要があります。 web.configファイルを使用し、コードの変更は不要です。これは、通常のデータベースプロバイダーの代わりにXMLファイルを使用してweb.configの2行を変更することにより、ローカルマシンでコードベースの製品バージョンをテストするのに非常に役立つことがわかりました。
私が言及し忘れたもう1つのことは、ベースクラスを拡張することで独自のカスタムプロバイダーをプラグインできることです。許可モデルを活用しながら、独自のストレージシステムを使用できます(たとえば、本当にしたい場合はビットマスク) 。
管理環境にいる場合は、Active Directoryまたは別のLDAP実装を使用できます。こうすることで、アクセス権を決定するセキュリティグループは、最初からサポートされている可能性があり、既によく知られている技術を使用して管理できます。
アプリがシュリンクラップされている場合は、データベースを正規化するというLevi Rosolの提案に対して+1して、アプリで拡張可能なデータモデルを使用できるようにします。
私は、あなたが提案しているものに似たいくつかのある程度制限された許可システムと、いくつかの本当にひどいシステムを見てきました。いくつかの単純な状況では、アプリケーションがより複雑にならない限り、それらは許容できます。ただし、非常に多くの場合、それらはより複雑になり、必要な機能に対応するためにシステムを書き直す必要があります。
いつか表現力が必要になると思われる場合は、ユーザーとグループ(またはロール)を備えた完全なACL(アクセス制御リスト)システムを使用します。つまり、アクセス許可によって管理される各要素(「ユーザーの管理」、「製品の管理」など)にはACLがあります。ACLは、アクセスできるすべてのユーザーとグループのリストです。その後、ユーザーは関連するACLに直接追加されるか、既にACLのメンバーであるグループに追加されます。
ACLはリストの実装を提案していますが、テーブルを使用した方が良いでしょう。 この答え は良い方法です。
許可は通常、1、0、またはnull(継承を示す)を持つキーワードです。ビットシステムでは、おそらくユーザーIDとアクセス許可キーワードにインデックスを作成できません。代わりに、許可値を取得するためにすべてのレコードをスキャンする必要があります。
私は最初のオプションに行くと言うでしょう。私にはより良い解決策のようです:
create table permissions (
user_id INT NOT Null,
permission VARCHAR(255) NOT NULL,
value TINYINT(1) NULL
)
alter table `permissions` ADD PRIMARY KEY ( `user_id` , `permission` )
私はSOが初めてなのでコメントできませんが、受け入れられた答えに関しては-このソリューションに伴う大きな利点は、コード内のあらゆる場所にあるif文や特殊な能力の代わりに、アクセス権を普遍的に処理できることです一時的な許可(有効期限のある許可)を許可するなど