<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>MySQL on Arch使いの日記</title>
    <link>https://blog.grainrigi.net/tags/mysql/</link>
    <description>Recent content in MySQL on Arch使いの日記</description>
    <generator>Hugo -- gohugo.io</generator>
    <copyright>Copyright © 2022, grainrigi; all rights reserved.</copyright>
    <lastBuildDate>Sun, 20 Nov 2022 22:08:47 +0900</lastBuildDate><atom:link href="https://blog.grainrigi.net/tags/mysql/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>【MySQL/MariaDB】突然のAccess denied for userエラーにはVIEWのDEFINERを疑え</title>
      <link>https://blog.grainrigi.net/post/mysql-accidental-logout/</link>
      <pubDate>Sun, 20 Nov 2022 22:08:47 +0900</pubDate>
      
      <guid>https://blog.grainrigi.net/post/mysql-accidental-logout/</guid>
      <description>
        
          
            MariaDBでユーザーアカウントの整理をしている際、突然以下のような権限エラーが発生するようになってしまった。
1ERROR 1045 (28000): Access denied for user &amp;#39;user&amp;#39;@&amp;#39;%&amp;#39; (using password: YES) 2(userは削除したのとは全く別の存在するユーザー) ちなみにこのエラーが発生したのは最初の接続時ではなくクエリの実行直後である。 そもそもこのエラーが最初の認証以外で起こること自体おかしい気がするが、 さらに言えばこのユーザーはちゃんと存在しているし、使用しているパスワードも完全に正しいのである。
ちなみにこのエラーを引き起こしていたクエリは普通のSELECT文だったのだが、 他のクエリと違ってビューに対するSELECTを発行していた。 調査したところ、どうもユーザーの削除によりビューの設定の整合性が失われ、 呼び出しているビューのセキュリティ機能で弾かれてしまっているらしい。
MySQLビューのセキュリティ そもそも、MySQLのビューがSELECT文で呼び出された場合、 結果セットを作るためにさらに内部でもう一度SELECT文を呼び出すわけだが、 内部でSELECT文を実行する際の権限は、必ずしも現在のユーザーの権限が用いられるわけではない。
具体的には、CREATE VIEWで指定できるDEFINERとSQL SECURITYというパラメーターによって定まる。
SQL SECURITY ビューのSELECT文を実行するユーザーの決定方法を指定する。DEFINERまたはINVOKERを指定できる SQL SECURITY = DEFINERの場合、DEFINER = [user]で指定されたユーザーの権限を用いる SQL SECURITY = INVOKERの場合、ビューを呼び出したユーザーの権限を用いる DEFINER SQL_SECURITY = DEFINERのときに参照されるユーザー このように、ビューを呼び出す際には、現在のユーザーの権限だけでなくDEFINERのユーザーの権限も参照する可能性があるのである。
DEFINERとユーザー削除 CREATE VIEWでビューを作る際に上記のパラメータを指定することはまず無いと思うが、 この場合、CREATE VIEWを呼び出したユーザーがDEFINERとなり、SQL SECURITYもDEFINERにセットされる。
では、このCREATE VIEWを呼び出したユーザーを後から削除した場合どうなるかというと、 ビューのDEFINERは自動で書き換わることはないため、 DEFINERは存在しないユーザーを参照することになる。 これにより、ビューを呼び出した際、 存在しないユーザーの権限を参照しようとするため、ERROR 1045 Access deniedが発生してしまうのである。
このようにして先述の現象が起こるというわけである。 (一つ納得がいかないのが、あたかも現在のユーザーのログイン権限が無いように表示されてしまうことであるが、 これ自体は仕様としか言いようがないのだろう。)
解決策 DEFINERに指定されたユーザーが存在しないのが問題なので、ALTER TABLEステートメントによりビューを再定義する。
1# はじめにビューの定義を持ってくる必要がある 2&amp;gt; SHOW CREATE VIEW my_view; 3+---------+---------------------- 4| View | Create View 5+---------+--------------------- 6| my_view | CREATE ALGORITHM=UNDEFINED DEFINER=`originaldefiner`@`%` SQL SECURITY DEFINER VIEW `my_view` AS select .
          
          
        
      </description>
    </item>
    
  </channel>
</rss>
