web-dev-qa-db-ja.com

PostgreSQLの特定のデータベースに権限を付与します

私はMySQLからPostgreSQLに移行し、ユーザー特権で壁にぶち当たりました。次のコマンドを使用して、データベースのすべてのテーブルにすべての特権をユーザーに割り当てることに慣れています。

# MySQL
grant all privileges on mydatabase.* to 'myuser'@'localhost' identified by 'mypassword';

PostgreSQL 9.xソリューションでは特権を「スキーマ」に割り当てる必要があるように見えますが、発行するSQLを正確に把握するために必要な労力は過剰であることが判明しています。さらに数時間の研究で答えが得られることは知っていますが、MySQLからPostgreSQLに移行する人は誰でも、シンプルで完全なレシピを提供するウェブ上に少なくとも1つのページがあると有益だと思います。これは、ユーザーに発行するために必要なコマンドです。新しいテーブルごとにコマンドを発行する必要はありません。

PostgreSQLでどのようなシナリオを異なる方法で処理する必要があるかはわかりませんので、過去に通常処理しなければならなかったいくつかのシナリオをリストします。すでに作成された単一のデータベースに対する特権を変更することだけを意味すると仮定します。

(1a)すべてのテーブルがまだ作成されていない、または(1b)テーブルがすでに作成されています。

(2a)ユーザーがまだ作成されていないか、(2b)ユーザーが既に作成されています。

(3a)特権がまだユーザーに割り当てられていない、または(3b)特権が以前にユーザーに割り当てられていた。

(4a)ユーザーは行の挿入、更新、選択、削除のみが必要です。(4b)ユーザーは表の作成と削除もできる必要があります。

私はすべてのデータベースにすべての特権を与える答えを見ましたが、それは私がここで望むものではありません。簡単なレシピを探していますが、説明も気にしません。

従来のショートカットのように、すべてのユーザーとすべてのデータベースに権限を付与したくありません。1人のユーザーが危険にさらされると、このアプローチはすべてのデータベースを危険にさらすからです。複数のデータベースクライアントをホストし、各クライアントに異なるログインを割り当てます。

USAGE列の増加する値を取得するにはserial特権も必要と思われますが、何らかの順序で許可する必要があります。私の問題はさらに複雑になりました。

22
Joe Lapp

Postgresの基本概念

ロールは、必要な特権が与えられた場合、dbクラスター内のすべてのデータベースにアクセスできるグローバルオブジェクトです。

clusterは多くのデータベースを保持し、多くのスキーマを保持します。異なるDBのスキーマ(同じ名前でも)は無関係です。スキーマの特権の付与は、現在のDB(付与時の現在のDB)のこの特定のスキーマにのみ適用されます。

すべてのデータベースは、デフォルトでスキーマpublicで始まります。それは慣習であり、多くの設定はそれから始まります。それ以外は、スキーマpublicは他のスキーマと同じです。

MySQLからは、スキーマレイヤーを完全に無視して、単一のスキーマpublicで開始することができます。データベースごとに定期的に数十のスキーマを使用しています。
スキーマは、ファイルシステムのディレクトリに少し似ています(完全ではありません)。

複数のスキーマを利用したら、search_path設定を理解してください:

デフォルトの権限

GRANT:のドキュメントごと

PostgreSQLは、PUBLICに特定の種類のオブジェクトに対するデフォルトの権限を付与します。デフォルトでは、テーブル、列、スキーマ、またはテーブルスペースのPUBLICに特権は付与されません。その他のタイプの場合、PUBLICに付与されるデフォルトの特権は次のとおりです。データベースの場合はCONNECTおよびCREATE TEMP TABLE。関数のEXECUTE特権。および言語のUSAGE特権。

これらのデフォルトはすべて ALTER DEFAULT PRIVILEGES で変更できます。

グループの役割

@ Craigがコメントしたように 、グループロールに対するGRANT特権を持ち、そのロールの特定のユーザーメンバーを作成するのが最善です(GRANTはユーザーロールに対するグループロールです) )。この方法により、特定のタスクに必要な特権のバンドルを簡単に処理して取り消すことができます。

グループロールは、ログインなしの単なる別のロールです。ログインを追加して、ユーザーロールに変換します。もっと:

レシピ

新しいデータベースmydb、グループmygrp、およびユーザーmyusrがあるとします...

問題のデータベースにスーパーユーザー(postgresなど)として接続している場合:

REVOKE ALL ON DATABASE mydb FROM public;  -- shut out the general public
GRANT CONNECT ON DATABASE mydb TO mygrp;  -- since we revoked from public

GRANT USAGE ON SCHEMA public TO mygrp;

あなたが書いたようにa user all privileges to all tablesを割り当てるには(私はもっと制限があるかもしれません):

GRANT ALL ON ALL TABLES IN SCHEMA public TO mygrp;
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO mygrp; -- don't forget those

将来のオブジェクトにデフォルトの権限を設定するには、このスキーマにオブジェクトを作成するevery roleに対して実行します:

ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON TABLES TO mygrp;

ALTER DEFAULT PRIVILEGES FOR ROLE myusr IN SCHEMA public
GRANT ALL ON SEQUENCES TO mygrp;

-- more roles?

次に、グループをユーザーに付与します。

GRANT mygrp TO myusr;

関連する回答:

代替(非標準)設定

MySQLから来て、データベースの特権を分離したいので、この非標準の設定db_user_namespaceを好むかもしれません。 ドキュメントごと:

このパラメーターは、データベースごとのユーザー名を有効にします。デフォルトではオフです。

マニュアルを注意深く読んでください。この設定は使用しません。上記を無効にしません。

51

特定のデータベースのすべてのテーブル(既存のテーブルとまだ作成されていないテーブル)の選択/挿入/更新/削除を特定のユーザーに許可する例を教えてください。

MySQLでデータベースと呼ぶものは、PostgreSQLデータベースよりもPostgreSQLスキーマに似ています。

データベース「test」にスーパーユーザーとして接続します。ここにある

$ psql -U postgres test

デフォルトの権限を変更する 既存のユーザー「テスター」に対して。

ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT INSERT, SELECT, UPDATE, DELETE ON TABLES
    TO tester;

デフォルトの権限を変更しても、既存のテーブルには影響しません。それは設計によるものです。既存のテーブルの場合、標準のGRANTおよびREVOKE構文を使用します。

存在しないユーザーに特権を割り当てることはできません。

従来のショートカットのように、すべてのユーザーとすべてのデータベースに権限を付与したくありません。1人のユーザーが危険にさらされると、このアプローチはすべてのデータベースを危険にさらすからです。複数のデータベースクライアントをホストし、各クライアントに異なるログインを割り当てます。

OK。テーブルを正しいロールに割り当てると、付与される特権はロール固有であり、すべてのユーザーに付与されるわけではありません!その後、rolesの付与先を決定できます。

  1. データベースごとにroleを作成します。ロールには多くのユーザーを保持できます。
  2. 次に、client-usernameを正しいロールに。
  3. また、your-username必要に応じて各役割に。


(1a)すべてのテーブルがまだ作成されていない、または(1b)テーブルがすでに作成されています。

OK。後でテーブルを作成できます。
準備ができたら、正しいクライアントroleにテーブルを割り当てます。

CREATE TABLE tablename();
CREATE ROLE rolename;
ALTER TABLE tablename OWNER TO rolename;


(2a)ユーザーがまだ作成されていないか、(2b)ユーザーが既に作成されています。

OK。準備ができたらユーザー名を作成します。クライアントで複数のユーザー名が必要な場合は、2番目のclient-username

CREATE USER username1;
CREATE USER username2;


(3a)特権がまだユーザーに割り当てられていない、または(3b)特権が以前にユーザーに割り当てられていた。

OK。権限を付与する準備ができたら、ユーザーを作成し、正しいロールを割り当てます。
GRANT-TOコマンドを使用して、ユーザーにロールを割り当てます。

GRANT rolename TO username1;
GRANT rolename TO username2;


(4a)ユーザーは行の挿入、更新、選択、削除のみが必要です。(4b)ユーザーは表の作成と削除もできる必要があります。

OK。これらのコマンドを実行して、ユーザーにアクセス許可を追加します。

GRANT SELECT, UPDATE, INSERT, DELETE ON dbname TO role-or-user-name;
ALTER USER username1 CREATEDB;
1
Red

PUBLICのみを使用する場合、スキーマについて忘れることができます。次に、次のようにします:( こちらのドキュメントを参照

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
    [, ...] | ALL [ PRIVILEGES ] }
    ON { [ TABLE ] table_name [, ...]
         | ALL TABLES IN SCHEMA schema_name [, ...] }
    TO { [ GROUP ] role_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]
0
Str.