【问题标题】:Minimum access levels to run MySql stored procedure运行 MySql 存储过程的最低访问级别
【发布时间】:2018-11-16 15:30:28
【问题描述】:

我正在尝试设置连接到 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 访问权限的简单测试也不起作用。

在不授予太多特权的情况下,我还能做些什么吗?

【问题讨论】:

  • 经过进一步调查,在这种情况下似乎只有 ROUTINE_DEFINITION 列为空,而当使用 root 查看 information_schema 时,此列被填充。

标签: c# mysql


【解决方案1】:

这似乎是 Connector/NET 中的一个错误,类似于 bug 75301,但略有不同。当它试图确定过程的参数元数据时,它首先创建一个名为ProceduresMySqlSchemaCollection,其中包含有关过程的所有 元数据。 (这是您在日志中看到的 SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess' 查询。)

Spike 用户帐户没有读取ROUTINE_DEFINITION 列的权限,所以它是NULL。连接器/NET 期望该字段为非 NULL 并抛出 SqlNullValueException 异常尝试读取它。

有两种解决方法:

1) 您发现的第一个方法是在您的连接字符串中设置CheckParameters=False。这将禁用存储过程元数据的检索(避免崩溃),但如果您没有完全正确地获取参数的顺序和类型,则可能会导致调用其他存储过程时出现更难调试的问题。 (Connector/NET 无法再使用元数据为您映射它们。)

2) 切换到不存在此错误的其他 ADO.NET MySQL 库:MySqlConnector on NuGet。与Connector/NET高度兼容,执行速度更快,修复了很多known issues

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-07
      相关资源
      最近更新 更多