Подтвердить что ты не робот

Пользователь не может получить доступ к базе данных

В моем PHP script я получаю доступ к двум базам данных db1 и db2. У меня есть пользователь [email protected], который может получить доступ к db1, но не может получить доступ к db2.

При выборе из таблицы mysql.user существует одна запись, и хост для этого пользователя является подстановочным знаком %, нет хоста localhost.

SELECT user, host FROM mysql.user WHERE user = 'myuser'; дай мне:

+------------+------+
| user       | host |
+------------+------+
| myuser     | %    |
+------------+------+
1 row in set (0.00 sec)

Глядя на GRANTS для этого пользователя, я вижу те же разрешения для db1, что и для db2

SHOW GRANTS FOR 'myuser'@'%';

+-----------------------------------------------------------------------------------------------------------+
| Grants for [email protected]%                                                                                   |
+-----------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...' |
| GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'%'                                                |
| GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'@'%'                                              |
+-----------------------------------------------------------------------------------------------------------+

В моем PHP script я могу получить доступ к db1, но я получаю сообщение об ошибке: INSERT command denied to user 'myuser'@'localhost' for table 'HISTORY'.

В нем указано, что пользователь [email protected], и люди предложили добавить разрешение для [email protected], однако, почему этот пользователь имеет доступ к db1, а не к db2?

4b9b3361

Ответ 1

localhost не соответствует % в MySQL. Похоже, он должен, но на самом деле это не так. Вам придется отдельно предоставлять привилегии [email protected], как для привилегии USAGE, так и для привилегий в каждой базе данных.

Или вы можете подключиться как [email protected], который соответствует %. Использование IP-адреса для localhost похоже, что он должен работать тождественно с localhost, но это не так. Вам нужно иметь две строки в таблице mysql.user (а также в таблице mysql.db в вашем случае), чтобы включить оба.

Чтобы продемонстрировать разницу между localhost и 127.0.0.1:

Соединение как mysql -h localhost использует интерфейс сокета UNIX и обходит TCP/IP. Это может быть немного лучше для производительности, но это влияет на сопоставление грантов, описанное выше.

Вы можете принудительно подключить локальное соединение TCP/IP, подключившись как mysql -h 127.0.0.1. Затем он подберет гранты, которые вы сделали для [email protected]%.

Таким образом, чтобы получить тот же пользователь, пароль и привилегии как для интерфейса сокета, так и для интерфейса TCP/IP, вам нужно будет выполнить все следующие утверждения:

GRANT USAGE ON *.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT USAGE ON *.* TO 'myuser'@'localhost' IDENTIFIED BY PASSWORD '*7733323232...'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'%'
GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'localhost'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'@'%'
GRANT ALL PRIVILEGES ON `db2`.* TO 'myuser'@'localhost'

Ответ 2

Если вы еще этого не сделали, вам нужно запустить flush privileges, чтобы mysql знал, что произошло изменение и перезагружает таблицу привилегий для пользователей:

FLUSH PRIVILEGES;

Ответ 3

Это очень не связано с GRANTs.

Очень распространенная причина наличия неправильных прав доступа из-за пользователей по умолчанию, существующих в MySQL. Специально для '' для User (анонимных пользователей) и/или Host в таблице mysql.user. Из-за того, как MySQL обрабатывает пользователей аутентификации и прокси-сервера и правила сортировки, используемые в записях таблицы mysql.user, можно было бы использовать неожиданный пользователь чем тот, который они использовали для аутентификации.

Используйте SELECT USER();, чтобы узнать подключаемого пользователя, который использовался во время аутентификации, и SELECT CURRENT_USER();, чтобы узнать эффективного пользователя , чьи привилегии применяются во время текущего сеанса.

И из http://dev.mysql.com/doc/refman/5.6/en/connection-access.html

Это распространенное заблуждение думать, что для данного имени пользователя все строки, которые явно указывают, что пользователь используется первым, когда сервер попытки найти соответствие для соединения. Это неправда. Если вы можете подключиться к серверу, но ваши привилегии не являются что вы ожидаете, вы, вероятно, аутентифицируетесь как некоторые другие счет.

A mysql.user таблица, аналогичная следующей

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ... (root from any host)
| %         | jeffrey  | ... (jeffrey from any host)
| localhost | root     | ... (root from localhost)
| localhost |          | ... (any user from localhost)
+-----------+----------+-

становится,

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

всякий раз, когда сервер считывает пользовательскую таблицу в память, чтобы обрабатывать несколько совпадений.
Когда клиент пытается подключиться, сервер просматривает строки в отсортированном порядке и использует первую строку, которая соответствует имени хоста клиента и имени пользователя.
Приоритет задается как: значения (IP-адрес, имя хоста, имя пользователя и т.д.) > '%' > ''

В большинстве случаев сервер/клиент приложений работает на том же хосте, что и база данных, в результате чего имя хоста выбирается как localhost во время аутентификации.
mysql -u jeffrey использует [email protected], который сопоставляется с ''@localhost вместо [email protected]%.

Выполнение $MYSQL_HOME/bin/mysql_secure_installation приведет к удалению анонимных пользователей при сохранении установки, уменьшая это неожиданное поведение.

Также проверьте:
[1] http://bugs.mysql.com/bug.php?id=36576 (проверить комментарий до последнего)
[2] http://bugs.mysql.com/bug.php?id=69570

Ответ 4

Просто подумал, что добавлю ответ. Я пытался это сделать на ubuntu. Пробовал гранты, флеши, ничего не работало (это сразу после apt-get install mysql-server). Только для усмешек я отскакивал от сервера, который работал, и мой новый пользователь теперь может войти в систему. Я сделал:

sudo service mysql restart

Я не знаю, что сработало, но это произошло.

Ответ 5

Вы также должны использовать привилегии GRANT для 'myuser' @'localhost':

GRANT ALL PRIVILEGES ON `db1`.* TO 'myuser'@'localhost';
GRANT ALL PRIVILEGES ON `db2_beta`.* TO 'myuser'@'localhost';

В противном случае анонимный пользователь @localhost, созданный во время установки db, имеет приоритет у вашего пользователя с именем подстановочного имени (%), как описано здесь:

http://dev.mysql.com/doc/refman/5.5/en/adding-users.html

Ответ 6

В соответствии с руководством mysql здесь:

Если вы изменяете таблицы грантов косвенно, используя управление учетными записями таких как GRANT, REVOKE или SET PASSWORD, уведомления сервера эти изменения и снова загружают таблицы предоставления в память немедленно.

Если вы изменяете таблицы грантов напрямую, используя такие выражения, как INSERT, UPDATE или DELETE, ваши изменения не влияют на привилегии проверяя, чтобы вы либо перезапустили сервер, либо попросите его перезагрузить столы. Если вы напрямую измените таблицы грантов, но забудьте перезагрузить их изменения не влияют, пока вы не перезапустите сервер. Эта может оставить вас задуматься, почему ваши изменения, похоже, не разница!

В большинстве случаев это действительно так. Тем не менее, в моей ситуации я работал с экземпляром mysql RDS Amazon Web Services (AWS). После многих неудачных попыток предоставить пользовательские разрешения я попробовал FLUSH PRIVILEGES, и база данных была немедленно видна пользователю. Если вы столкнетесь с этим при поиске решения на платформе Amazon Web Services RDS, вы можете попробовать попробовать и посмотреть, помогает ли это.

Этот вопрос SO содержит наиболее полные решения этой проблемы и является первым в большинстве результатов поиска, поэтому я хотел добавить этот ответ для тех, кто использует RDS. Надеюсь, он некоторое время сохранит администраторов RDS.

Ответ 7

Я столкнулся с той же проблемой в прошлом. Вы пробовали следующее?

GRANT ALL ON `db1`.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...';
GRANT ALL ON `db2`.* TO 'myuser'@'%' IDENTIFIED BY PASSWORD '*7733323232...';
FLUSH PRIVILEGES;