DBMSでは、管理者は次のようなものを使用して、ユーザーにテーブルアクセスを許可できます。
GRANT ALL ON mydb.mytbl1, mydb.mytbl2 TO 'someuser'@'somehost';
しかし、すべてのテーブルをユーザーに許可し、それらの一部へのアクセスを明示的にブロックすることは可能ですか?例(BLOCKキーWordは偽のキーであり、説明のためにのみ使用されます。):
GRANT ALL ON mydb.* TO 'someuser'@'somehost';
BLOCK ALL ON mydb.mytbl3 TO 'someuser'@'somehost';
別のアイデアは、GRANTステートメントにwhere句を追加することです。ただし、GRANTステートメントの構文では許可されていないようです( http://dev.mysql.com/doc/refman/5.1/en/grant.html )。
この種類のアクセス制御は、管理者がほとんどの場合(1000テーブルなど)でユーザーを信頼し、少数の上位機密テーブルへのアクセスのみをブロックする場合に便利です。
そのようなメカニズムが存在するかどうか教えてください。
私はこの特定の問題を解決する必要があり、「これら以外のすべてのテーブル」と言う方法がないことに気付きました。
これを回避するために行ったのは、内部データベース、restricted_tablesを作成することでした。
シンプルなテーブルスキーマがいくつかありました。
CREATE TABLE `tables` (
`TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '',
`TABLE_NAME` varchar(64) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `authorized_users` (
`authorization_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user` char(16) NOT NULL,
`table_schema` char(64) NOT NULL,
`table_name` char(64) NOT NULL,
`authorization_ticket` char(16) NOT NULL,
`authorization_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`authorization_expiration` date DEFAULT NULL,
PRIMARY KEY (`authorization_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
表示されるtables
テーブルは、「これら以外のすべて」リストから除外するテーブルスキーマ(DB名)とテーブル名のペアです。
許可されたユーザーのテーブルは、特定のユーザーが他の方法でデフォルトの制限されたテーブルにアクセスできるようにするために、2回目の反復で導入されました。他のいくつかの列には、監査証跡用の内部チケットシステムへの参照であるチケット列と、作成と有効期限のいくつかの日付列があります。
次に、次のようなクエリを実行するユーザーメンテナンススクリプトがあります。
$q="select i.table_schema, i.table_name from information_schema.tables i left outer join
restricted_tables.tables r using(table_schema, table_name)
where
i.table_schema not in (".buildEscapedList($db,$excludedDbs).") and r.table_schema is null
union
select table_schema, table_name from restricted_tables.authorized_users where user=?";
(これは、PHPで説明されている場合)で記述された永続的なステートメントです。$ excludedDbsは、mysql、information_schemaなどの完全に無視するスキーマのリストでした。
次に、ユーザーの「すべての権限を取り消す」を実行して開始します(これにより、 ''で識別されるuser @ Hostの使用法が残ります。
次に、そのクエリによって返されるすべてのテーブルをループして選択を許可します。
これはあなたの以外のものすべてを効果的に実装します
嫌なもの
新しいテーブルが追加されると、db。*のように、ユーザーに明示的に含まれません。スクリプトのバージョンがcron上で実行され、これらのユーザーに定期的にreadd権限が付与されることを緩和するため。
これは、user @ Hostのショー許可を見るときに、ユーザーがアクセスしたりアクセスしたりしていないことをすばやく理解するのに少し手間がかかります(ただし、grepで解決できないものはありません)。
既知の制限
スクリプトは、これによって管理されているアカウントが選択アクセスのみを必要とするシナリオ用に作成されたもので、テーブルごとに他のさまざまなCRUD特権のプロビジョニングはありません。
代替ソリューション
制限されているmydb内のテーブルのサブセットがある場合、それらのテーブルのみをmydb_restrictedデータベースに移動します。次に、db。*スタイルの付与のみを保持して、特権アカウントへのmydb_restricted。*アクセスを付与できます。
MySQLの場合、GRANT
コマンドに加えて、REVOKE
コマンドもあります。ただし、REVOKE
には制限があります。
もし、あんたが GRANT ALL ON mydb.* TO 'someuser'@'somehost'
を実行して1つのテーブルを削除することはできませんREVOKE ALL ON mydb.mytbl3 TO 'someuser'@'somehost'
。
これは、REVOKE
が付与された権限のみを削除するためです。つまり、次のことができます。
REVOKE ALL ON mydb.* TO 'someuser'@'somehost'
もちろん、各テーブルに個別に自動的にGRANT
アクセスするスクリプトを作成することもできます。次に、「troublesomeuser」@「somehost」から削除する必要があるテーブルアクセスをREVOKE
する特別なスクリプトを作成できます。
GRANT
またはREVOKE
が有効なコマンドであるかどうかに関係なく、最後に実行されたコマンドに注意してください。
MySQL構文にはDENY
コマンドはありません。これは、他のいくつかのSQL実装で定義されている機能です。しかし、権利を否定することには多くの人がつまずいた独自の落とし穴があります。
GoogleのMySQLツールはこれをサポートしています: https://code.google.com/p/google-mysql-tools/source/browse/#svn%2Ftrunk%2Fpermissions_lib
これは本当に複雑なソリューションです。 SQL権限をドメイン固有のPython=言語に変換する必要がありますが、データベース/テーブル/列の取り消し、テンプレート化などの柔軟性を提供します。Pythonデータベースに接続してデータベース/テーブル/列をリストし、パーミッションをデータベースにプッシュするか、SQL出力をダンプするインタープリターを介してファイル。
これは、テーブル名をクエリするストアドプロシージャを使用して実現できます。機密性の高いものを除外し、それらをループして、それぞれに許可を設定します。
同じロールを複数のユーザーに簡単に割り当てるためのロールもチェックアウトします。
https://dev.mysql.com/doc/refman/8.0/en/roles.html
そのリンクにはより良い例がありますが、あなたのユースケースではおそらく:
CREATE ROLE 'app_admin', 'app_user';
GRANT ALL ON app_db.* TO 'app_admin';
GRANT ALL ON app_db.table1, app_db.table2 TO 'app_user';
GRANT 'app_admin' TO 'admin1'@'localhost';
GRANT 'app_user' TO 'user1'@'localhost';
SET DEFAULT ROLE 'app_admin' to 'admin1'@'localhost';
SET DEFAULT ROLE 'app_user' to 'user1'@'localhost';
デフォルトの役割は、すべての接続で機能するようになっています。
また、必須のロール機能もお見逃しなく。