运行mysql存储过程的最低访问级别

4nkexdtk  于 2021-06-15  发布在  Mysql
关注(0)|答案(2)|浏览(296)

我正在尝试设置连接到mysql数据库8.0的.net 4.7.1程序,以使用运行的最低权限。net程序正在使用mysql.data建立连接。用户执行存储过程的最低权限通常只有execute特权。这在mysql工作台或命令行中运行良好。
在运行.net程序时,会返回以下异常:system.data.sqltypes.sqlnullvalueexception:'数据为null。不能对空值调用此方法或属性。'
为了简单起见,我创建了一个非常小的演示程序来演示这个问题。
数据库设置:

CREATE DATABASE Spike;

CREATE PROCEDURE TestAccess()
BEGIN
END;

CREATE USER Spike@localhost IDENTIFIED WITH mysql_native_password BY 'sample';

GRANT EXECUTE ON PROCEDURE `TestAccess` TO Spike@localhost;

设置程序代码:

static void Main(string[] args)
{
    using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database=Spike;uid=Spike;pwd=sample"))
    {
        conn.Open();
        Console.WriteLine("Connection open");
        MySqlCommand cmd = new MySqlCommand();
        cmd.Connection = conn;
        cmd.CommandText = "TestAccess";
        cmd.CommandType = System.Data.CommandType.StoredProcedure;
        cmd.ExecuteNonQuery();

        Console.WriteLine("Query executed");
    }
    Console.ReadKey();
}

撞车发生在线路上 cmd.ExecuteNonQuery(); 来自崩溃的堆栈很有趣,因为它似乎表明查询了信息模式。记录所有语句时,我可以看到异常之前的最后一条语句是:

SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess'

我不能在information\u schema上授予不同的权限,但是我可以在存储过程上授予更多的权限,以便在routines表中显示更多的信息,但是这感觉是错误的。授予create和alter访问权限的简单测试也不起作用。
我还能做些什么,而不给你太多的特权吗?

js4nwp54

js4nwp541#

这似乎是connector/net中的一个bug,类似于bug 75301,但有点不同。当它试图确定过程的参数元数据时,它首先创建一个 MySqlSchemaCollection 命名 Procedures 所有关于这个过程的元数据(这就是 SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess' 您在日志中看到的查询。)
这个 Spike 用户帐户无权读取 ROUTINE_DEFINITION 列,就是这样 NULL . connector/net期望此字段为非null,并抛出一个 SqlNullValueException 尝试读取时出现异常。
有两种解决方法:
1) 你发现的第一个问题是 CheckParameters=False 在连接字符串中。这将禁用对存储过程元数据的检索(避免崩溃),但如果没有正确地获取参数的顺序和类型,则调用其他存储过程可能会导致调试困难的问题(connector/net无法再使用元数据为您Map它们。)
2) 切换到另一个没有这个bug的ado.net mysql库:nuget上的mysqlconnector。它与connector/net高度兼容,执行速度更快,并修复了许多已知问题。

jmo0nnb3

jmo0nnb32#

我找到了一个我很满意的答案。它通过添加checkparameters=false来更改连接字符串:

using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database=Spike;uid=Spike;pwd=sample;CheckParameters=false"))

这将禁用参数检查,从而禁用模式查询中的信息。

相关问题