【问题标题】:Connect to MySQL database w/ C# as non-root user?以非 root 用户身份连接到带有 C# 的 MySQL 数据库?
【发布时间】:2015-11-26 02:13:06
【问题描述】:

首先让我说我对数据库完全陌生,但一直在阅读他们的 MySQL 教程。

现在,我正在尝试制作一个应用程序,该应用程序允许非特权用户(非 root)通过 C# GUI 应用程序连接并在数据库上执行一些命令。用户将使用 Windows 身份验证登录到数据库。

现在,我能够制作一个快速 GUI,运行程序的人可以使用“root”连接到本地主机上的数据库并获取其中的任何内容。

我的问题是,我究竟如何允许用户以非 root 权限进行连接?我唯一能找到的所有交易都使用带有“root”的连接字符串作为用户。

编辑:数据库已经创建。我个人将无法以 root 用户身份连接到它并授予其他用户权限。

【问题讨论】:

    标签: c# mysql database windows windows-authentication


    【解决方案1】:

    这里显示的表格中的行也是一些重要的概念:

    select user,host,password from mysql.user where user='pfinferno';
    

    重要提示,用户可以有多个主机名或通配符。每个人都有自己的权利和密码。虽然上面的密码是经过哈希处理的,但至少你可以快速观察一下,看看是否所有密码都匹配(例如 root 有 3 个帐户)。

    主机列由以下值填充,主要是:

    标本A:

    • 本地主机
    • 127.0.0.1
    • %
    • md21.newyork.comcastbusiness.net 等常用名称

    % 值是通配符。它是为了灵活性,但与 'root'@'%' 之类的用户一起使用时可能会非常危险。强烈建议仅在样本 A 中将 root 保留为前两个。此外,前两个在不同的工具中完全不同。我的建议是为前两个设置一个 root 用户行,并保持密码相同。这种方法有利有弊。但请记住,当您无法连接时,其他依赖于连接的东西,无论是代理、phpmyadmin、工具、my.conf 设置等。您将重新审视这一点。

    在 Mureinik 给出的示例中,它向具有通配符 host = % 的用户授予权限。这意味着它依赖于这样创建的用户。请注意,通常以这种方式设置用户帐户。虽然没有什么限制你把它锁得更紧。


    当一个用户尝试连接到服务器时,他最终连接的用户可以被解析为不同的用户/主机组合,如在没有本地主机(主机)用户或普通用户的情况下可以看到 -名称,而是主机值为通配符 % 的名称。可以通过以下查询看到这一点:

    标本 B:

    select current_user(),user();
    

    后者是连接尝试呈现的用户,前者是已解决且实际的用户。正如在这些论坛中所看到的那样,这些影响可能会导致人们在调试中浪费数天时间。有些人几天都连接不上,我是认真的。

    试样 C:

    create user 'pfinferno'@'localhost' identified by 'thePassword';
    create user 'pfinferno'@'127.0.0.1' identified by 'thePassword';
    create user 'pfinferno' identified by 'thePassword';
    create user 'pfinferno'@'md21.newyork.comcastbusiness.net' identified by 'thePassword';
    

    -- 上面的注释 #3 与 'pfinferno'@'%' 相同

    现在允许,主机名可以是普通用户的通配符,主机名可以是 localhost 和 127.0.0.1 仅适用于 root。但在尝试锁定安全性时,管理员通常会根据传入的主机名创建用户帐户(例如 Specimen C,第 4 行),并基于此更改安全性。管理它可能有点压倒性。所以他们经常只是说去死吧,我会创建通配符用户。 Susie 说,这对新用户来说可能没问题,但对于 Secimen C 第 4 行,如果你要进来,你可以在第 3 行用户上获得你不会接受的授权。因此,解析您的实际用户(参见样本 B),从最具体的主机名到回退到更通用的主机名,直到找到通配符等。

    不幸的是,用户本身并没有使用指定的主机名进行连接,他们就是他们自己。他们试图联系。所以你不要说嘿我想成为这个东西@hostname,你就是你自己。您是 'pfinferno'@'md21.newyork.comcastbusiness.net',但可能会退回到通配符。

    如果用户在通配符% 中被丢弃在样本 Cexcept 中,那么您最好获得您所期望的与他们一起获得的授权,因为您现在是一个新用户。

    尽量限制在授权语句中使用通配符,不要像在惰性方法中那样执行*.*,这只会授予对所有数据库和表的权限。在 Mureinik 的示例中,它适用于一个数据库中的所有表。不是太寒酸。尝试微调权限,例如向不需要的用户授予或根本不授予对表的 SELECT 权限。小心WITH GRANT OPTION,就像在网上看到的那样,剪切和粘贴。如果你使用它,你只是授予用户权限授予其他用户权限。

    SSH 隧道

    您可能不想使用 Secimen A host = % 通配符(除了明显的 We are Risk Averse 除外)的一个原因是

    create user 'pfinferno'@'localhost' identified by 'thePassword';
    

    非常适合 SSH 隧道。您将通过 PKI 的加密安全通道进行连接,并以 @ localhost 的身份展示自己。这大大降低了安全风险。


    为什么我无法连接?

    希望下面几乎没有评论的视觉效果可以说明我为什么将这个部分命名为我所做的。

    drop user 'pfinferno'@'localhost';
    drop user 'pfinferno'@'127.0.0.1';
    drop user 'pfinferno'@'%';
    drop user 'pfinferno'@'md21.newyork.comcastbusiness.net';
    flush privileges; -- some say this is not necessary, I have found otherwise
    
    create user 'pfinferno'@'localhost' identified by 'thePassword';
    create user 'pfinferno'@'127.0.0.1' identified by 'thePassword';
    create user 'pfinferno' identified by 'thePassword';
    create user 'pfinferno'@'md21.newyork.comcastbusiness.net' identified by 'thePassword';
    

    ...

    select user,host,password from mysql.user where user='pfinferno';
    
    grant all on so_gibberish.* to 'pfinferno'@'%'; -- grant all rights on so_gibberish db
    
    flush privileges; -- some say this is not necessary, I have found otherwise
    

    看看一些赠款。

    show grants for 'pfinferno'@'localhost';    -- sandboxed. Can just log in and sit there
    +-----------------------------------------------------------------------------------------+
    | Grants for pfinferno@localhost                                                          |
    +-----------------------------------------------------------------------------------------+
    | GRANT USAGE ON *.* TO 'pfinferno'@'localhost' IDENTIFIED BY PASSWORD '*74692AE70C53...' |
    +-----------------------------------------------------------------------------------------+
    
    show grants for 'pfinferno'@'127.0.0.1';    -- sandboxed. Can just log in and sit there
    same as above
    
    show grants for 'pfinferno'; -- wildcard % user, has all rights on so_gibberish;
    +-----------------------------------------------------------------------------------------+
    | Grants for pfinferno@%                                                                  |
    +-----------------------------------------------------------------------------------------+
    | GRANT USAGE ON *.* TO 'pfinferno'@'%' IDENTIFIED BY PASSWORD '*74692AE70C53...'         |
    | GRANT ALL PRIVILEGES ON `so_gibberish`.* TO 'pfinferno'@'%'                             |
    +-----------------------------------------------------------------------------------------+
    

    请注意上面GRANT USAGE 意味着您至少有权登录和坐下(沙盒)。但是通配符%user 也拥有so_gibberish db 的全部权利。

    现在我通过mysql -u pfinferno -pthePassword进入mysql提示符

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    +--------------------+
    
    mysql> select current_user(),user();
    +---------------------+---------------------+
    | current_user()      | user()              |
    +---------------------+---------------------+
    | pfinferno@localhost | pfinferno@localhost |
    +---------------------+---------------------+
    

    尝试的用户 (user()) 被解析为相同的 (current_user())。我被沙盒化了,除了select now() 无聊到死,基本上什么都做不了。

    mysql> use so_gibberish;
    ERROR 1044 (42000): Access denied for user 'pfinferno'@'localhost' to database 'so_gibberish'
    

    以该用户身份退出 mysql CLI。

    现在

    drop user 'pfinferno'@'localhost';
    drop user 'pfinferno'@'127.0.0.1';
    drop user 'pfinferno'@'md21.newyork.comcastbusiness.net';
    

    我刚刚放弃了四分之三的 pfinferno 用户

    通过mysql -u pfinferno -pthePassword进入mysql提示符

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | so_gibberish       |
    +--------------------+
    
    mysql> select current_user(),user();
    +----------------+---------------------+
    | current_user() | user()              |
    +----------------+---------------------+
    | pfinferno@%    | pfinferno@localhost |
    +----------------+---------------------+
    
    mysql> use so_gibberish;
    Database changed
    

    这表明 @CLI(或任何程序)来自任何主机,连接尝试首先由用户提供,然后解析为实际(分别参见 user()current_user() 的输出) .

    因此,也许奇怪的是,当我删除用户时,EFFECTIVE RIGHTS 随着用户被解析为不同的用户而增加。这可能是数小时/数天/数周调试的主题。用户可能不知道他们真正登录的是谁(已解决),或者为什么他们不能,顺便说一下,每个人都可以有不同的密码!对于用户root 尤其如此,在mysql.user 中有几行......并且考虑到所有mysql 用户中可能有50% 最初是作为开发人员连接到它的。只是一个猜测。

    【讨论】:

      【解决方案2】:

      嗯,首先,您必须意识到这个“root”(来自 MySQL)不同于“root”用户(来自您的计算机)。

      当您登录 MySQL 数据库时(首先以 root 身份),您可以创建另一个具有最低权限的用户。 (创建用户:https://dev.mysql.com/doc/refman/5.1/en/create-user.html

      之后,您可以向该特定用户授予(授予)一些权限。 (授予权限:https://dev.mysql.com/doc/refman/5.1/en/grant.html) 例如,您可以允许某些用户仅从表中选择数据。另一个用户可以插入/更新。以此类推。

      因此,在您的应用程序中,您可以指定另一个用户而不是 root,就像您通常看到的那样。

      【讨论】:

      • 如果我不是管理数据库的人或类似的人,会有什么不同吗?我只是严格地提供一个 GUI 供用户使用,因为他们无权访问命令行。
      • 好吧,如果您将所有权限授予用户,他们将能够为所欲为。因此,只授予您知道他们不会删除数据、插入过多数据等的权限。您可以选择可以向用户授予访问权限的表。
      • 如果您认为这个答案可以帮助您解决问题,请接受这个答案吗?
      【解决方案3】:

      您可以使用grant 语法,如root 向其他用户授予权限。例如:

      GRANT ALL PRIVILEGES ON mydatabase.* TO pfinferno
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-08
        • 1970-01-01
        • 2018-10-15
        • 2017-07-08
        • 2017-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多