多くの場合に機能する「usecurrent_user()」または実際には機能しない「useuser()」に答える前に、以下をお読みください...
ユーザーが接続するIPアドレスによって制御され、テーブル内の特定の行へのユーザーアクセスを制限するビューをテーブルに作成しようとしています。
私の最初の試みは次のようになりました:
create table testtable (
`RowID` bigint not null auto_increment,
`owner` varchar(64),
`key` varchar(64),
`val` varchar(64),
primary key (`RowID`)
);
create view testview (
`RowID`,
`owner`,
`key`,
`val`
) as select
`testtable`.`RowID` as `RowID`,
`testtable`.`owner` as `owner`,
`testtable`.`key` as `key`,
`testtable`.`val` as `val`
from testtable
where (testtable.owner = substring_index(current_user(), '@', -1));
create user 'testuser'@'192.168.3.30' identified by 'testpass';
grant select, insert, update, delete on testview to 'testuser'@'192.168.3.30';
これで、ホスト192.168.3.30からtestuserとしてログインし、次のようなことを実行してselect * from testview
、自分に適用されるtesttableの適切なサブセットを取得できるようになるはずです。
上記は機能しません。それが機能しない理由は、デフォルトでcurrent_user()
ビューの定義者を返し、定義者が誰であるかに応じて、データがないか、(さらに悪いことに)間違ったデータになるためです。呼び出しcurrent_user()
元のユーザーを返したい場合は、句を使用してビューを作成する必要があります。これにより、セキュリティ特権も呼び出し元のユーザーの権限に制限されるため、コードの本来の目的が無効になります。SQL SECURITY INVOKER
使用したいのですuser()
が、残念ながら、ほとんどの場合、IPアドレスではなくホスト名/ドメインが返されます。
明確でない場合の注意:この場合、PHP(またはRuby、perlなど)でIPアドレスを取得することは役に立ちません。私はデータベースのセキュリティを少し設定しているので、クライアントに依存することは明らかに不十分です。SQLにIPアドレスが必要です。
アイデア/リファレンス/コンテキストを探している好奇心旺盛な方へ:
参考までに、この気の利いたセキュリティトリックのアイデアはここから得ましたが、IPアドレスの代わりにユーザー名を使用しているため、これがはるかに簡単になります。私の場合、ホスト自体から部分的に更新されたホストのデータベースをセットアップしようとしています。ホストごとに異なるユーザーを設定したくはありませんが、各ホストが独自のレコード(ファイルシステム、ファンの速度、温度など)を更新できるようにしたいです。