Spec-Zone.ru › MySQL 8.4

8.2.6 Управление доступом, этап 1: Проверка подключения

При попытке подключения к серверу MySQL сервер принимает или отклоняет подключение в зависимости от этих условий:

  • Ваша личность и возможность её подтверждения путём предоставления соответствующих учетных данных.

  • Разблокирован или заблокирован ваш аккаунт.

Сервер сначала проверяет учетные данные, а затем состояние блокировки аккаунта. Неудача на любом шаге приводит к полному отказу сервера в доступе. В противном случае сервер принимает подключение, переходит к этапу 2 и ожидает запросов.

Сервер выполняет проверку личности и учетных данных, используя столбцы в таблице user, принимая подключение только в случае выполнения этих условий:

  • Имя хоста клиента и имя пользователя соответствуют столбцам Host и User в строке некоторой таблицы user. Правила, регулирующие допустимые значения Host и User, см. в разделе 8.2.4 «Указание имён учётных записей».

  • Клиент предоставляет учетные данные, указанные в строке (например, пароль), как указано в столбце authentication_string. Учетные данные интерпретируются с использованием плагина аутентификации, указанного в столбце plugin.

  • В строке указано, что учетная запись разблокирована. Состояние блокировки записывается в столбце account_locked, который должен иметь значение 'N'. Блокировку аккаунта можно установить или изменить с помощью CREATE USER или ALTER USER оператора.

Ваша личность определяется двумя параметрами:

  • Ваше имя пользователя MySQL.

  • Хост клиента, с которого вы подключаетесь.

Если значение столбца User не пустое, имя пользователя в входящем соединении должно точно совпадать. Если значение User пустое, оно соответствует любому имени пользователя. Если строка таблицы user, соответствующая входящему подключению, имеет пустое имя пользователя, пользователь считается анонимным пользователем без имени, а не пользователем с именем, которое фактически указал клиент. Это означает, что пустое имя пользователя используется для всех дальнейших проверок доступа в течение сеанса подключения (то есть во время этапа 2).

Столбец authentication_string может быть пустым. Это не подразумевает, что подходит любой пароль. Это означает, что пользователь должен подключиться без указания пароля. Метод аутентификации, реализованный плагином, который аутентифицирует клиента, может или не может использовать пароль в столбце authentication_string. В этом случае возможно, что для аутентификации на сервере MySQL используется также внешний пароль.

Значения паролей, не являющиеся пустыми, хранящиеся в столбце authentication_string таблицы user, зашифрованы. MySQL не хранит пароли в виде открытого текста, доступного для просмотра. Скорее, пароль, предоставленный пользователем, пытающимся подключиться, шифруется (используя метод хэширования пароля, реализованный плагином аутентификации аккаунта). Зашифрованный пароль затем используется в процессе подключения для проверки правильности пароля. Это делается без передачи зашифрованного пароля по соединению. См. раздел 8.2.1 «Имена пользователей и пароли учётных записей».

С точки зрения сервера MySQL, зашифрованный пароль является истинным паролем, поэтому вы никогда не должны предоставлять к нему доступ. В частности, не предоставляйте пользователям, не обладающим правами администратора, доступ для чтения к таблицам в базе данных системы mysql.

В следующей таблице показано, как различные комбинации значений User и Host в таблице user применяются к входящим подключениям.

User Значение Host Значение Допустимые подключения
'fred' 'h1.example.net' fred, подключаясь с h1.example.net
'' 'h1.example.net' Любой пользователь, подключающийся с h1.example.net
'fred' '%' fred, подключающийся с любого хоста
'' '%' Любой пользователь, подключающийся с любого хоста
'fred' '%.example.net' fred, подключающийся с любого хоста в домене example.net
'fred' 'x.example.%' fred, подключающийся с x.example.net, x.example.com, x.example.edu и т. д.; это, вероятно, бесполезно
'fred' '198.51.100.177' fred, подключающийся с хоста с IP-адресом 198.51.100.177
'fred' '198.51.100.%' fred, подключающийся с любого хоста в подсети класса C 198.51.100
'fred' '198.51.100.0/255.255.255.0' Аналогично предыдущему примеру

Возможно, что имя хоста клиента и имя пользователя входящего подключения соответствуют более чем одной строке в таблице user. Предыдущий набор примеров демонстрирует это: несколько записей соответствуют подключению с h1.example.net от fred.

Когда возможны несколько совпадений, сервер должен определить, какое из них использовать. Он решает эту проблему следующим образом:

  • Когда сервер считывает таблицу user в память, он сортирует строки.

  • Когда клиент пытается подключиться, сервер просматривает строки в отсортированном порядке.

  • Сервер использует первую строку, которая соответствует имени хоста и имени пользователя клиента.

Сервер использует правила сортировки, которые ставят строки с наиболее конкретными значениями Host на первое место:

  • Буквальные IP-адреса и имена хостов являются наиболее конкретными.

  • Для учётных записей с IP-адресом в части хоста порядок специфичности такой:

    • Учётные записи, у которых часть хоста указана как IP-адрес:

      CREATE USER 'user_name'@'127.0.0.1';
      CREATE USER 'user_name'@'198.51.100.44';
      
    • Учётные записи, у которых часть хоста указана как IP-адрес с использованием CIDR-нотации:

      CREATE USER 'user_name'@'192.0.2.21/8';
      CREATE USER 'user_name'@'198.51.100.44/16';
      
    • Учётные записи, у которых часть хоста указана как IP-адрес с маской подсети:

      CREATE USER 'user_name'@'192.0.2.0/255.255.255.0';
      CREATE USER 'user_name'@'198.51.0.0/255.255.0.0';
      
  • Шаблон '%' означает “любой хост” и является наименее конкретным.

  • Пустая строка '' также означает “любой хост”, но сортируется после '%'.

Подключения, не являющиеся TCP (файлы сокетов, именованные каналы и общая память), обрабатываются как локальные подключения и соответствуют части хоста localhost, если имеются такие учётные записи, или частям хостов с подстановками, которые соответствуют localhost в противном случае (например, local%, l%, %).

Обработка '%' как эквивалентного localhost устарела; ожидается, что это поведение будет удалено в будущих версиях MySQL.

Строки с одинаковым значением Host упорядочиваются в порядке возрастания наиболее конкретных значений User. Пустое значение User означает “любой пользователь” и является наименее конкретным, поэтому для строк с одинаковым значением Host неанонимные пользователи сортируются перед анонимными.

Для строк с одинаково специфичными значениями Host и User порядок является недетерминированным.

Чтобы увидеть, как это работает, предположим, что таблица user выглядит так:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-

Когда сервер считывает таблицу в память, он сортирует строки, используя описанные правила. Результат после сортировки выглядит так:

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-

При попытке подключения клиента сервер просматривает отсортированные строки и использует первое найденное соответствие. Для подключения с localhost от jeffrey две строки из таблицы соответствуют: та, что имеет значения Host и User равными 'localhost' и '', и та, что имеет значения '%' и 'jeffrey'. Строка 'localhost' появляется первой в отсортированном порядке, поэтому сервер использует именно её.

Вот ещё один пример. Предположим, что таблица user выглядит так:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| h1.example.net |          | ...
+----------------+----------+-

Отсортированная таблица выглядит так:

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| h1.example.net |          | ...
| %              | jeffrey  | ...
+----------------+----------+-

Первая строка соответствует подключению любого пользователя с h1.example.net, тогда как вторая строка соответствует подключению jeffrey с любого хоста.

END_OF_DOCUMENT_MARKER
Примечание

Распространенное заблуждение состоит в том, что для данного имени пользователя при попытке сервера найти соответствие для подключения сначала используются все строки, явно указывающие этого пользователя. Это не так. Приведенный пример иллюстрирует это: подключение от h1.example.net пользователя jeffrey сначала сопоставляется не со строкой, содержащей 'jeffrey' в качестве значения столбца User, а со строкой без имени пользователя. В результате jeffrey аутентифицируется как анонимный пользователь, хотя при подключении он указал имя пользователя.

Если вы можете подключиться к серверу, но ваши привилегии не такие, как ожидалось, вы, вероятно, аутентифицируетесь под другим пользователем. Чтобы узнать, под какой учетной записью сервер выполнил аутентификацию, используйте функцию CURRENT_USER(). (См. Раздел 14.15, «Функции информации».) Она возвращает значение в формате user_name@host_name, которое указывает значения User и Host из соответствующей строки таблицы user. Предположим, что jeffrey подключается и выполняет следующий запрос:

mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost     |
+----------------+

Результат, показанный здесь, указывает на то, что у соответствующей строки таблицы user было пустое значение столбца User. Другими словами, сервер обрабатывает jeffrey как анонимного пользователя.

Другой способ диагностики проблем с аутентификацией — вывести таблицу user и вручную отсортировать её, чтобы увидеть, где происходит первое сопоставление.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/connection-access.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API