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

时间:2018-11-16 15:30:28

标签: c# mysql

我试图设置连接到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();行 崩溃产生的堆栈很有趣,因为它似乎表明已查询了information_schema。当记录所有语句时,我可以看到异常之前的最后一条语句是:

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

我不能授予对information_schema的不同权限,但是我可以赋予存储过程更多的权限,以使更多信息在例程表中可见,但是,这是错误的。授予CREATE和ALTER访问权限的简单测试也不起作用。

在不授予过多特权的情况下我还能做些其他事情吗?

2 个答案:

答案 0 :(得分:3)

我找到了一个令我非常满意的答案。通过添加 CheckParameters = false

来更改连接字符串。
E3

这将禁用参数检查,从而禁用information_schema查询。

答案 1 :(得分:3)

这似乎是Connector / NET中的错误,类似于bug 75301,但有一点不同。在尝试确定过程的参数元数据时,它首先使用有关该过程的 all 元数据创建一个名为MySqlSchemaCollection的{​​{1}}。 (这是您在日志中看到的Procedures查询。)

SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess'用户帐户无权读取Spike列,因此是ROUTINE_DEFINITION。 Connector / NET期望此字段为非NULL,并尝试尝试读取它时抛出NULL异常。

有两种解决方法:

1)您首先发现的是在连接字符串中设置SqlNullValueException。这将禁用对存储过程元数据的检索(避免崩溃),但是如果您不完全正确地获得参数的顺序和类型,可能会导致难以调试的问题调用其他存储过程。 (Connector / NET无法再使用元数据为您映射它们。)

2)切换到另一个没有此错误的ADO.NET MySQL库:MySqlConnector上的NuGet。它与Connector / NET高度兼容,执行速度更快,并修复了许多known issues