認証プラグインを使用した MySQL サーバーへの認証が発生すると、接続中の (外部) ユーザーを権限チェックのために別のユーザーとして処理するようにプラグインから要求されることがあります。これにより、外部ユーザーを 2 番目のユーザーのプロキシにすることができます。つまり、2 番目のユーザーの権限を持つことができます。言い換えると、外部ユーザーは「プロキシユーザー」 (偽装できるユーザーまたは別のユーザーと呼ばれるようになるユーザー) であり、2 番目のユーザーは「プロキシ対象ユーザー」 (プロキシユーザーが実行できるアイデンティティーを持つユーザー) です。
このセクションでは、プロキシユーザー機能の動作について説明します。認証プラグインに関する一般的な情報については、セクション6.3.7「プラガブル認証」を参照してください。プロキシユーザーがサポートされている独自の認証プラグインを作成することに関心がある場合は、セクション24.2.4.9.4「認証プラグインでのプロキシユーザーサポートの実装」を参照してください。
プロキシ処理を発生させるには、次の条件を満たす必要があります。
接続中のクライアントがプロキシユーザーとして処理されるときに、プラグインはプロキシ対象ユーザーの名前を示すために、別の名前を返す必要があります。
プロキシユーザーのアカウントがプラグインで認証されるように設定する必要があります。
CREATE USER
またはGRANT
ステートメントを使用して、アカウントをプラグインに関連付けます。プロキシユーザーのアカウントは、プロキシ対象アカウントの
PROXY
権限を持つ必要があります。これを行うには、GRANT
ステートメントを使用します。
次のような定義について検討します。
CREATE USER 'empl_external'@'localhost'
IDENTIFIED WITH auth_plugin AS 'auth_string';
CREATE USER 'employee'@'localhost'
IDENTIFIED BY 'employee_pass';
GRANT PROXY
ON 'employee'@'localhost'
TO 'empl_external'@'localhost';
クライアントがローカルホストから
empl_external
として接続すると、MySQL
は auth_plugin
を使用して認証を実行します。auth_plugin
が ('auth_string'
の内容に基づいて、おそらく一部の外部認証システムを参照することで)
サーバーに employee
というユーザー名を返す場合は、このクライアントを権限チェックのために、employee
ローカルユーザーとして処理するように求めるサーバーへのリクエストとして機能します。
この場合、empl_external
はプロキシユーザー、employee
はプロキシ対象ユーザーです。
サーバーは empl_external
が
employee
に対する
PROXY
権限を持っているかどうかをチェックすることで、empl_external
ユーザーに対して employee
のプロキシ認証を実行できることを確認します。(この権限が付与されていない場合は、エラーが発生します。)
プロキシ処理が発生したときに、USER()
および CURRENT_USER()
関数を使用すると、接続中のユーザーと現在のセッション中に権限が適用されるアカウントとの相違点を確認できます。先ほど説明した例では、これらの関数は次の値を返します。
mysql> SELECT USER(), CURRENT_USER();
+-------------------------+--------------------+
| USER() | CURRENT_USER() |
+-------------------------+--------------------+
| empl_external@localhost | employee@localhost |
+-------------------------+--------------------+
認証プラグインの名前を指定する IDENTIFIED
WITH
句のあとに、ユーザーの接続時にサーバーがプラグインに渡す文字列を指定する
AS
句が続く場合があります。AS
句が必要であるかどうかは、各プラグインに依存します。必要な場合、認証文字列の形式は、プラグインを使用する目的によって異なります。許可される認証文字列の値については、特定のプラグインに関するドキュメントを参照してください。
プロキシ権限の付与
外部ユーザーが別のユーザーとして接続し、その権限を持つことができるようにするには、特別な
PROXY
権限が必要です。この権限を付与するには、GRANT
ステートメントを使用します。例:
GRANT PROXY ON 'proxied_user' TO 'proxy_user';
proxy_user
は、接続時に外部で認証された有効な MySQL
ユーザーを表している必要があります。そうでない場合は、接続の試行に失敗します。proxied_user
は、接続時にローカルで認証された有効なユーザーを表している必要があります。そうでない場合は、接続の試行に失敗します。
対応する REVOKE
構文は次のとおりです。
REVOKE PROXY ON 'proxied_user' FROM 'proxy_user';
MySQL GRANT
および
REVOKE
構文の拡張機能は、通常どおりに動作します。例:
GRANT PROXY ON 'a' TO 'b', 'c', 'd';
GRANT PROXY ON 'a' TO 'd' IDENTIFIED BY ...;
GRANT PROXY ON 'a' TO 'd' WITH GRANT OPTION;
GRANT PROXY ON 'a' TO ''@'';
REVOKE PROXY ON 'a' FROM 'b', 'c', 'd';
前述の例では、''@''
はデフォルトのプロキシユーザーであり、「任意のユーザー」を意味します。デフォルトのプロキシユーザーについては、このセクションの後半で説明します。
次のような場合に、PROXY
権限を付与できます。
自分で
proxied_user
による: アカウント名のユーザー名とホスト名の両方の部分で、USER()
の値がCURRENT_USER()
およびproxied_user
と完全に一致する必要があります。proxied_user
に対するGRANT PROXY ... WITH GRANT OPTION
を持つユーザーによる。
MySQL のインストール時にデフォルトで作成された
root
アカウントは、''@''
(つまり、すべてのユーザー) に対する
PROXY ... WITH GRANT
OPTION
権限を持っています。これにより、root
はプロキシユーザーを設定したり、プロキシユーザーを設定するための権限をほかのアカウントに委任したりできます。たとえば、root
は次の操作を実行できます。
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'test';
GRANT PROXY ON ''@'' TO 'admin'@'localhost' WITH GRANT OPTION;
この時点で、admin
ユーザーは特定のすべての GRANT
PROXY
マッピングを管理できます。たとえば、admin
は次の操作を実行できます。
GRANT PROXY ON sally TO joe;
デフォルトのプロキシユーザー
一部またはすべてのユーザーが特定の外部プラグインを使用して接続するように指定するには、「空白の」
MySQL
ユーザーを作成し、そのプラグインを使用して認証するように設定し、(空白のユーザーとは異なる場合に)
プラグインが認証された実際のユーザー名を返すことができるようにします。たとえば、LDAP
認証を実装する ldap_auth
という名前の仮のプラグインが存在すると仮定します。
CREATE USER ''@'' IDENTIFIED WITH ldap_auth AS 'O=Oracle, OU=MySQL';
CREATE USER 'developer'@'localhost' IDENTIFIED BY 'developer_pass';
CREATE USER 'manager'@'localhost' IDENTIFIED BY 'manager_pass';
GRANT PROXY ON 'manager'@'localhost' TO ''@'';
GRANT PROXY ON 'developer'@'localhost' TO ''@'';
ここで、クライアントが次のように接続を試みるとします。
mysql --user=myuser --password='myuser_pass' ...
サーバーでは、MySQL ユーザーとして定義された
myuser
が見つかりません。ただし、クライアントのユーザー名およびホスト名と一致する空白のユーザーアカウント
(''@''
)
があるため、サーバーはそのアカウントと照合してクライアントを認証します。サーバーは
ldap_auth
を呼び出して、それをユーザー名とパスワードとして
myuser
および myuser_pass
に渡します。
ldap_auth
プラグインによって、myuser_pass
が
myuser
の正しいパスワードでないことが LDAP
ディレクトリで検出された場合は、認証に失敗し、サーバーは接続を拒否します。
パスワードが正しく、ldap_auth
によって myuser
が開発者であることが検出された場合は、MySQL
サーバーに myuser
ではなく、developer
というユーザー名が返されます。サーバーは、(実行するための
PROXY
権限を持っているため) ''@''
が
developer
として認証できることを確認し、接続を受け入れます。セッションは、developer
の権限を持っている myuser
で続行されます。(これらの権限は、DBA が
GRANT
ステートメントを使用して設定するべきですが、表示されません。)USER()
および CURRENT_USER()
関数は、次の値を返します。
mysql> SELECT USER(), CURRENT_USER();
+------------------+---------------------+
| USER() | CURRENT_USER() |
+------------------+---------------------+
| myuser@localhost | developer@localhost |
+------------------+---------------------+
代わりに、プラグインによって
myuser
がマネージャーであることが
LDAP
ディレクトリで検出された場合は、ユーザー名として
manager
が返され、セッションは
manager
の権限を持つ
myuser
で続行されます。
mysql> SELECT USER(), CURRENT_USER();
+------------------+-------------------+
| USER() | CURRENT_USER() |
+------------------+-------------------+
| myuser@localhost | manager@localhost |
+------------------+-------------------+
単純にするために、外部認証はマルチレベルで実行できません。前述の例では、developer
の証明書も、manager
の証明書も考慮されません。ただし、クライアントが
developer
または manager
アカウントと照合して直接認証を試みる場合は、引き続き使用されます
(そのため、これらのアカウントにはパスワードを割り当てられるはずです)。
デフォルトのプロキシアカウントは、任意のホストと一致する
''
をホスト部分で使用します。デフォルトのプロキシユーザーを設定する場合は、ホスト部分で
'%'
を含むアカウントもチェックするように注意してください。その理由は、これらのアカウントは任意のホストにも一致しますが、サーバー内部でアカウント行をソートする際に使用されるルールによって、''
よりも優先されるためです
(セクション6.2.4「アクセス制御、ステージ 1: 接続の検証」を参照してください)。
MySQL のインストールに、次の 2 つのアカウントが含まれていると仮定します。
CREATE USER ''@'' IDENTIFIED WITH some_plugin;
CREATE USER ''@'%' IDENTIFIED BY 'some_password';
1 番目のアカウントの目的は、それ以外の場合は、より具体的なアカウントと一致しないユーザーの接続を認証する際に使用されるデフォルトのプロキシユーザーとして機能することです。2 番目のアカウントは、たとえば、匿名ユーザーとして独自のアカウントを持っていないユーザーを有効にするために、作成されることがあります。
ただし、この構成では、一致のルールによって
''@''
よりも先に ''@'%'
がソートされるため、1
番目のアカウントは使用されません。より具体的などのアカウントにも一致しないアカウントの場合、サーバーは
''@''
ではなく、''@'%'
と照合して認証を試みます。
デフォルトのプロキシユーザーを作成する場合は、デフォルトのプロキシユーザーよりも優先されるために、そのユーザーが目的どおりに動作することを妨げるその他の既存の「任意のユーザーに一致する」アカウントがないかどうかチェックします。このようなアカウントをすべて削除する必要がある場合もあります。
プロキシユーザーのシステム変数
次の 2 つのシステム変数は、プロキシのログインプロセスをトレースする際に役立ちます。
-
proxy_user
: プロキシ処理が使用されていない場合、この値はNULL
です。それ以外の場合は、プロキシユーザーのアカウントを示します。たとえば、クライアントがデフォルトのプロキシアカウントを使用して認証する場合、この変数は次のように設定されます。mysql> SELECT @@proxy_user; +--------------+ | @@proxy_user | +--------------+ | ''@'' | +--------------+
external_user
: 認証プラグインは外部ユーザーを使用して、MySQL サーバーへの認証を行うことがあります。たとえば、Windows のネイティブ認証を使用するときは、Windows の API を使用して認証するプラグインに、ログイン ID を渡す必要がありません。ただし、認証には引き続き Windows ユーザー ID が使用されます。このプラグインは、読み取り専用のセッション変数external_user
を使用して、この外部ユーザー ID (または最初の 512 UTF-8 バイト) をサーバーに返すことがあります。プラグインがこの変数を設定しない場合、その値はNULL
です。