MySQL8.0におけるROLEによるユーザー権限管理についての確認。
MySQL5.7からProxy Userを利用する事で、ROLEと同じように権限をまとめて管理する事が出来るようになりましたが、MySQL8.0からは正式にROLEが追加されて、複数ROLEの切り替えやROLEのネストが出来るようになります。これにより、多くのユーザーを管理するような環境では、権限管理工数やミスが削減出来る事になるかと思います。
7.3.4 Using Roles
https://dev.mysql.com/doc/refman/8.0/en/roles.html
ROLEの作成とROLEへの権限付与
mysql> CREATE ROLE role80; Query OK, 0 rows affected (0.01 sec) mysql> GRANT ALL on DEMO.* TO role80; Query OK, 0 rows affected (0.05 sec) mysql> create user user01 identified by 'password'; Query OK, 0 rows affected (0.01 sec) mysql> select host, user, authentication_string from mysql.user; +-----------+-----------+-------------------------------------------+ | host | user | authentication_string | +-----------+-----------+-------------------------------------------+ | % | role80 | | | % | root | *E74858DB86EBA20BC33D0AECAE8A8108C56B17FA | | % | user01 | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 | | localhost | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | +-----------+-----------+-------------------------------------------+ 4 rows in set (0.02 sec)
USER01にrole80の権限を付与
ROLE権限を付与する前は、何も権限を付与していない為、information_schemaのみ確認可能。
[root@DockerHost oracle]# docker exec -it mysql8 mysql -uuser01 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 8.0.0-dmr MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ 1 row in set (0.00 sec) mysql> grant role80 to user01; Query OK, 0 rows affected (0.02 sec) mysql> select * from mysql.role_edges; +-----------+-----------+---------+---------+-------------------+ | FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION | +-----------+-----------+---------+---------+-------------------+ | % | role80 | % | user01 | N | +-----------+-----------+---------+---------+-------------------+ 1 row in set (0.06 sec) mysql> select * from mysql.default_roles; Empty set (0.00 sec) mysql>
ユーザーのDEFAULT ROLEを設定しログイン時に反映させる
mysql> alter user user01 default role role80; Query OK, 0 rows affected (0.01 sec) mysql> select * from mysql.default_roles; +------+--------+-------------------+-------------------+ | HOST | USER | DEFAULT_ROLE_HOST | DEFAULT_ROLE_USER | +------+--------+-------------------+-------------------+ | % | user01 | % | role80 | +------+--------+-------------------+-------------------+ 1 row in set (0.00 sec) mysql>
権限が継承されているかログインして確認してみる
[root@DockerHost oracle]# docker exec -it mysql8 mysql -uuser01 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.0-dmr MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | DEMO | | information_schema | +--------------------+ 2 rows in set (0.00 sec) mysql> select user(),current_user(),current_role(); +------------------+----------------+----------------+ | user() | current_user() | current_role() | +------------------+----------------+----------------+ | user01@localhost | user01@% | `role80`@`%` | +------------------+----------------+----------------+ 1 row in set (0.00 sec) mysql> show grants; +--------------------------------------------------+ | Grants for user01@% | +--------------------------------------------------+ | GRANT USAGE ON *.* TO `user01`@`%` | | GRANT ALL PRIVILEGES ON `DEMO`.* TO `user01`@`%` | | GRANT `role80`@`%` TO `user01`@`%` | +--------------------------------------------------+ 3 rows in set (0.00 sec) mysql> show grants for user01; +------------------------------------+ | Grants for user01@% | +------------------------------------+ | GRANT USAGE ON *.* TO `user01`@`%` | | GRANT `role80`@`%` TO `user01`@`%` | +------------------------------------+ 2 rows in set (0.01 sec) mysql> show grants for user01 using role80; +--------------------------------------------------+ | Grants for user01@% | +--------------------------------------------------+ | GRANT USAGE ON *.* TO `user01`@`%` | | GRANT ALL PRIVILEGES ON `DEMO`.* TO `user01`@`%` | | GRANT `role80`@`%` TO `user01`@`%` | +--------------------------------------------------+ 3 rows in set (0.00 sec) mysql>
補足:Default Roleを設定しない場合
確認用アカウントuser02を作成
mysql> create user user02 identified by 'password'; Query OK, 0 rows affected (0.07 sec) mysql> grant role80 to user02; Query OK, 0 rows affected (0.01 sec) mysql>
Deault Roleが無い場合は、ログイン後にSETコマンドでROLEを選択する
[root@DockerHost oracle]# docker exec -it mysql8 mysql -uuser02 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 11 Server version: 8.0.0-dmr MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | +--------------------+ 1 row in set (0.01 sec) mysql> select user(),current_user(),current_role(); +------------------+----------------+----------------+ | user() | current_user() | current_role() | +------------------+----------------+----------------+ | user02@localhost | user02@% | NONE | +------------------+----------------+----------------+ 1 row in set (0.00 sec) mysql> set role role80; Query OK, 0 rows affected (0.00 sec) mysql> select user(),current_user(),current_role(); +------------------+----------------+----------------+ | user() | current_user() | current_role() | +------------------+----------------+----------------+ | user02@localhost | user02@% | `role80`@`%` | +------------------+----------------+----------------+ 1 row in set (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | DEMO | | information_schema | +--------------------+ 2 rows in set (0.00 sec) mysql>
再起動するとSETコマンドで設定した値は消えるので、必要に応じて”set default role”コマンドでDefault Roleを設定する
mysql> set default role role80 to user02; Query OK, 0 rows affected (0.01 sec) mysql> select user(),current_user(),current_role(); +------------------+----------------+----------------+ | user() | current_user() | current_role() | +------------------+----------------+----------------+ | user02@localhost | user02@% | NONE | +------------------+----------------+----------------+ 1 row in set (0.00 sec) mysql> exit Bye [root@DockerHost oracle]# docker exec -it mysql8 mysql -uuser02 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 13 Server version: 8.0.0-dmr MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> select user(),current_user(),current_role(); +------------------+----------------+----------------+ | user() | current_user() | current_role() | +------------------+----------------+----------------+ | user02@localhost | user02@% | `role80`@`%` | +------------------+----------------+----------------+ 1 row in set (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | DEMO | | information_schema | +--------------------+ 2 rows in set (0.00 sec) mysql>
その他参考:roleはpassword_expireとaccount_lockedで設定されている
通常のアカウント同様に利用したい場合、必要であればexpiredとlockedを解除してあげる。
mysql> select host, user, authentication_string,password_expired,account_locked from mysql.user; +-----------+-----------+-------------------------------------------+------------------+----------------+ | host | user | authentication_string | password_expired | account_locked | +-----------+-----------+-------------------------------------------+------------------+----------------+ | % | role80 | | Y | Y | | % | root | *E74858DB86EBA20BC33D0AECAE8A8108C56B17FA | N | N | | % | user01 | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 | N | N | | % | user02 | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 | N | N | | localhost | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | N | Y | +-----------+-----------+-------------------------------------------+------------------+----------------+ 5 rows in set (0.01 sec) mysql>
ユーザーに複数のROLEの権限を付与してみる
先ずは、ROLEを追加作成してsakilaデータベースに権限付与してみる
mysql> CREATE ROLE role81; Query OK, 0 rows affected (0.01 sec) mysql> GRANT ALL on sakila.* TO role81; Query OK, 0 rows affected (0.01 sec) mysql> grant role81 to user01; Query OK, 0 rows affected (0.01 sec) mysql> select * from mysql.role_edges; +-----------+-----------+---------+---------+-------------------+ | FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION | +-----------+-----------+---------+---------+-------------------+ | % | role80 | % | user01 | N | | % | role80 | % | user02 | N | | % | role81 | % | user01 | N | +-----------+-----------+---------+---------+-------------------+ 3 rows in set (0.00 sec) mysql>
Default Roleはrole80になっているので、DEMOデータベースのみにアクセス出来るが、SETコマンドでroleを切り替える事が出来る。
[root@DockerHost oracle]# docker exec -it mysql8 mysql -uuser01 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 14 Server version: 8.0.0-dmr MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | DEMO | | information_schema | +--------------------+ 2 rows in set (0.01 sec) mysql> select user(),current_user(),current_role(); +------------------+----------------+----------------+ | user() | current_user() | current_role() | +------------------+----------------+----------------+ | user01@localhost | user01@% | `role80`@`%` | +------------------+----------------+----------------+ 1 row in set (0.00 sec) mysql> set role role81; Query OK, 0 rows affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | sakila | +--------------------+ 2 rows in set (0.00 sec) mysql> select user(),current_user(),current_role(); +------------------+----------------+----------------+ | user() | current_user() | current_role() | +------------------+----------------+----------------+ | user01@localhost | user01@% | `role81`@`%` | +------------------+----------------+----------------+ 1 row in set (0.00 sec) mysql>
ROLEにROLE権限をネストして付与してみる
mysql> grant role81 to role80; Query OK, 0 rows affected (0.01 sec) mysql> select * from mysql.role_edges; +-----------+-----------+---------+---------+-------------------+ | FROM_HOST | FROM_USER | TO_HOST | TO_USER | WITH_ADMIN_OPTION | +-----------+-----------+---------+---------+-------------------+ | % | role80 | % | user01 | N | | % | role80 | % | user02 | N | | % | role81 | % | role80 | N | | % | role81 | % | user01 | N | +-----------+-----------+---------+---------+-------------------+ 4 rows in set (0.01 sec) mysql> show grants for role80@'%'; +--------------------------------------------------+ | Grants for role80@% | +--------------------------------------------------+ | GRANT USAGE ON *.* TO `role80`@`%` | | GRANT ALL PRIVILEGES ON `DEMO`.* TO `role80`@`%` | | GRANT `role81`@`%` TO `role80`@`%` | +--------------------------------------------------+ 3 rows in set (0.00 sec) mysql> show grants for role81@'%'; +----------------------------------------------------+ | Grants for role81@% | +----------------------------------------------------+ | GRANT USAGE ON *.* TO `role81`@`%` | | GRANT ALL PRIVILEGES ON `sakila`.* TO `role81`@`%` | +----------------------------------------------------+ 2 rows in set (0.00 sec)
role80のメンバーのuser01でログインして、付与された権限を確認してみる。
role80には、role81の権限が付与されているのでDEMOとsakilaデータベース共にアクセス可能になっている。
mysql> select user(),current_role(); +------------------+----------------+ | user() | current_role() | +------------------+----------------+ | user01@localhost | `role80`@`%` | +------------------+----------------+ 1 row in set (0.00 sec) mysql> show grants; +----------------------------------------------------+ | Grants for user01@% | +----------------------------------------------------+ | GRANT USAGE ON *.* TO `user01`@`%` | | GRANT ALL PRIVILEGES ON `DEMO`.* TO `user01`@`%` | | GRANT ALL PRIVILEGES ON `sakila`.* TO `user01`@`%` | | GRANT `role80`@`%`,`role81`@`%` TO `user01`@`%` | +----------------------------------------------------+ 4 rows in set (0.01 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | DEMO | | information_schema | | sakila | +--------------------+ 3 rows in set (0.00 sec) mysql>