1. ホーム
  2. データベース
  3. ポストグレスキュー

Postgresqlのデータベース権限まとめ

2022-01-19 06:30:04

Postgresqlデータベースは、柔軟なアクセス権の管理をサポートしています、あなたはテーブルの読み取り、書き込み、更新、削除およびその他の操作のアクセス権にロール(グループ、ユーザー)を制御することができます、関数のアクセス権を実行し、(使用、更新など)ビュー、シーケンス権限を操作する。

PGの権限管理はより強力で、ユーザーがテーブルのパスワード・フィールドにアクセスすることを禁止するなど、テーブルの個々のフィールドに細かく設定することができます。詳しい説明はこの記事の後半で行う。

PGデータベースではユーザーとロールは一律にロールと呼ばれ、作成文もcreate role XXXとなっていますが、それでもユーザーとロールの間には若干の違いがあります。この場合、ログイン権を持つユーザーをrole、ログイン権を持たないロールをroleと呼び、これを区別するために使用します。

実際、管理ツールPgAdminでは、ログイン権限のないものはグループロール、ログイン権限のあるものはログインロールと、ユーザーとロールの違いを確認することができます。

基本的なパーミッション

ユーザーやロールには、データベース作成権限、スーパーユーザー権限、ロール作成権限など、基本的な権限を与えることができます。

例えば、ユーザーを作成するための文は次のようになります。

CREATE ROLE guest LOGIN
 NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;

なお、上記のRole guestはLOGIN権限を持っているので、ユーザーと呼んでください。

ロールを作成するための文は

CREATE ROLE "group"
 NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;

ここではLOGINパーミッションがないので、ロールであることに注意してください。

上記のロールやユーザー作成文は、スーパーユーザーやデータベース作成などの権限を与えるものではありません。

データベースオブジェクトのアクセス権を操作する

データベースオブジェクトの操作権限は、ログイン権限を持たないロールにのみ割り当てることができ、ログイン権限を持つユーザーには直接割り当てられません。

そこで、ログインしたユーザーがデータベース・オブジェクトを操作する権利をどのように制御するかという疑問が生じます。

答えは、ユーザーをロールのメンバーにすることです。そうすれば、ロールの特権が与えられ、ログインしたユーザーのデータベース・オブジェクトへのアクセスはさらに制限されます。

ゲストユーザーに上記のロールグループを付与した場合。

GRANT "group" TO guest;

その後、ゲスト・ユーザーはグループ・ロールが持つデータベース・オブジェクトの特権を持つようになります。

例えば、グループ・ロールがクラス・テーブルに対してのみInsert操作を行うように制御する場合。

GRANT INSERT ON TABLE class TO "group";

この時点では、ゲストユーザーでデータにログインした後、テーブルクラスに対してINSERT操作のみ可能で、deleteやupdateなどの操作は行えません。

ゲストユーザーでログインし、TESTデータベース配下のclassテーブルにアクセスするサンプルコードは以下のとおりです。

Server [localhost]:
Database [postgres]:
Port [5433]:
Username [postgres]: guest
User guest's password.
psql (9.4.5)
Type "help" to get help information.
postgres=> \c TEST
You are now connected to the database "TEST", user "guest".
TEST=> select * from class;
ERROR: permission denied for relation class
TEST=> insert into class values(2,'class1');
INSERT 0 1


上記の結果から、ゲスト・ユーザーはクラス・テーブルを照会する権限を持っていませんが、データベースへの挿入は可能であることがわかります。これは、グループロールがクラステーブルの挿入権限のみを与え、そしてゲストユーザがクラステーブルの挿入権限のみを持つためです。

前述のように、PGの権限管理はテーブルの特定のフィールドに絞り込むことができるので、引き続きクラステーブルとゲストユーザーで実験してみましょう。

TEST=> \c postgres postgres;
You are now connected to the database "postgres",user "postgres".
postgres=# \c TEST;
You are now connected to the database "TEST",user "postgres".
TEST=# grant select(num) on class to "group";
GRANT
TEST=# \echo switch to the postgres user to connect to the TEST database and grant select permission to the num field of the class table to the group role
switch to the postgres user to connect to the TEST database, and give the group role to the select permission of the num field of the class table
TEST=# \c TEST guest
Password for user guest.
You are now connected to the database "TEST",user "guest".
TEST=> \echo switch back to guest user to log into TEST database
Switch back to the guest user logging into the TEST database
TEST=> select * from class;
ERROR: permission denied for relation class
TEST=> select num from class;
 num
-----
  1
  2
(2 rows of records)


上記の結果からわかるように、ゲスト・ユーザーはまだクラス・テーブルを問い合わせる権限を持っていませんが、クラス・テーブルの num フィールドを問い合わせる権限を持っています。

PGデータベースでは、テーブルの操作権限だけでなく、シーケンス、関数、ビューなど、他のデータベースオブジェクトも制御することができます。

PGの権限制御は非常に強力なんですね。

追記 Postgresのユーザーによるデータベースへのアクセス権

データベースへのユーザー権限(ログイン、スーパーユーザー権限)

(1) 現在のデータベースにユーザーhighgoとユーザーaが存在することを確認する。

highgo=#\du
               List of roles
 Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
 a | | {}
 highgo | Superuser, Create role, Create DB, Replication | {}


(2) 現在接続しているユーザーがスーパーユーザーのhighgoであること、そのユーザーが作成したロールやデータベース権限などを持っていることを確認する。

highgo=#select current_user;
 current_user
--------------
 highgo
(1row)


(3) 現在のクラスタ内のデータベースを表示する

highgo=#\l
               List of databases
  Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+--------+----------+------------+------------+-------------------
 highgo | highgo | UTF8 | zh_CN.utf8 |zh_CN.utf8 |
 template0 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo +
      | | | | | highgo=CTc template1 | highgo | UTF8 | zh_CN.utf8 | zh_CN.utf8 | =c/highgo + | | | | highgo=CTc      | | | | | highgo=CTc(3rows)


(4) データベースに通常のユーザーaで接続する。

highgo=#\c highgo a
Youare now connected to database "highgo" as user "a".
highgo=>select current_user;
 current_user
--------------
 a
(1row)
(5) use super user highgo to connect to the database normally
highgo=>\c highgo highgo
Youare now connected to database "highgo" as user "highgo".
highgo=#select current_user;
 current_user
--------------
 highgo
(1row)


(6) スーパーユーザーがhighgoに接続した後、通常ユーザーaがデータベースに接続できないように設定します。

highgo=#alter role a nologin;
ALTER ROLE
highgo=#\c highgo a
Fatal error: The role "a" was not allowed to log in
Previousconnection kept
highgo=#


(7) スーパーユーザーがhighgoに接続した後、一般ユーザーaにデータベースへの接続を許可しないように設定し、ユーザーaにスーパーユーザー権限を与えた後、まだデータベースに接続できない。

highgo=#alter role a superuser;
ALTERROLE
highgo=#\du
               List of roles
 Role name | Attributes | Member of
-----------+------------------------------------------------+-----------
 a | Superuser, Cannot login | {}
 highgo | Superuser, Create role, Create DB, Replication | {}
 
highgo=#\c highgo a
Fatal error: The role "a" was not allowed to log in
Previousconnection kept


(8) ユーザーaにデータベースへのログイン権限を与えた後、ユーザーaはデータベースへのログインが可能になります。

highgo=#alter role a login;
ALTERROLE
highgo=#\c highgo a
Youare now connected to database "highgo" as user "a".
highgo=#select current_user;
 current_user
--------------
 a
(1row)


上記は私の個人的な経験ですが、参考にしていただき、BinaryDevelopをより支持していただければと思います。もし、間違いや不完全な考察があれば、遠慮なくアドバイスしてください。