代码之家  ›  专栏  ›  技术社区  ›  Coding Monkey

添加数据的SQL权限以及如何验证?

  •  1
  • Coding Monkey  · 技术社区  · 16 年前

    我正在寻找一种好方法来维护对谁可以在C应用程序和SQL Server 2005中将数据添加到数据库的权限。

    我需要解释清楚。因此,让我们举一个例子:

    我有两个用户 Bob Jim ,两者都已添加到SQL权限中,因此它们对数据库具有写访问权限。现在,所有访问都基于域用户帐户。所有其他用户只有读取权限。

    现在我有几张桌子,比如:

    • 用户
    • 用户权限
    • 图书出版商

    所以 UserPermissions 包含用户和图书出版商的列表。例如: 鲍勃 有权为添加图书 MS Press 吉姆 有权为添加图书 O'Reilly .

    现在我需要验证这些信息并限制它们可以添加的内容。

    所以说 吉姆 从命令行使用我的应用程序,他编写了如下内容:

    Addbook.exe "C# 3.0 in a Nutshell" "O'Reilly"

    这个工具应该继续,把书添加到书桌上。

    现在说 鲍勃 尝试相同的命令,该工具应该出错,因为他没有添加书籍的权限 奥赖利 .

    现在我需要知道如何做一些事情。

    • 验证用户是否首先具有对SQL Server的写权限
    • 验证用户是否具有要添加的写入权限 books 由特定的发布者
    • 此外,在工具实际尝试添加数据之前,我需要验证上述情况是否正确,即在工具继续之前,我需要先验证反馈

    现在,我不是100%担心用户注入恶意数据,虽然这是很好的阻止,但它是一个内部工具,我想我可以信任用户…(可能)

    不管怎样,我不知道从哪里开始,我的SQL技能非常缺乏。

    AKK,最后一件事,我不想使用存储过程添加数据。

    3 回复  |  直到 16 年前
        1
  •  5
  •   Eric    16 年前

    好吧,让我们把这个分解一下:

    验证用户是否可以写入表(如果为真,则返回1,否则返回0):

    SELECT isnull(has_perms_by_name('MyDb.dbo.MyTable', 'OBJECT', 'INSERT'), 0)
    

    验证用户是否可以写入该发布服务器:

    SELECT count(*) FROM UserPermissions WHERE
    UserName = 'username' AND Publisher = 'publisher'
    

    现在,这就是这些的SQL,而不是实际的C。要获得c中的值:

    SqlConnection SqlConn = new SqlConnection("connection_string_goes_here");
    SqlCommand SqlCmd = new SqlCommand();
    
    SqlConn.Open();
    SqlCmd.Connection = SqlConn;
    SqlCmd.CommandText = "SELECT isnull(has_perms_by_name('MyDb.dbo.MyTable', " +
        "'OBJECT', 'INSERT'), 0)"
    
    if (SqlCmd.ExecuteScalar())
    {
       SqlCmd.CommandText =
           "SELECT count(*) FROM UserPermissions WHERE " +
           "Username = " + System.Environment.UserDomainName + "\" + 
               System.Environment.UserName + " " +
           AND Publisher = @Publisher";
       SqlCmd.Parameters.Add("@Publisher", SqlDbType.NVarChar);
       SqlCmd.Parameters("@Publisher").Value = PublisherInput;
    
       if(SqlCmd.ExecuteScalar())
       {
           SqlCmd.Parameters.Clear();
           SqlCmd.CommandText = "INSERT INTO Books (Title, Publisher) VALUES " +
                                "(@Title, @Publisher)";
           SqlCmd.Parameters.Add("@Title", SqlDbType.NVarChar);
           SqlCmd.Parameters.Add("@Publisher", SqlDbType.NVarChar);
           SqlCmd.Parameters("@Title").Value = TitleInput;
           SqlCmd.Parameters("@Publisher").Value = PublisherInput;
           SqlCmd.ExecuteNonQuery();
       }
    }
    
    SqlCmd.Dispose();
    SqlConn.Close();
    SqlConn.Dispose();
    

    作为最后一点, 净化你的输入 . 在应用程序中使用参数,以及 不要信任任何用户,即使是内部用户 . 我不能再强调了。

    编辑:因为有不止一种方法可以剥猫皮,我觉得不包括linq-to-sql解决方案(至少包括count问题)是愚蠢的:

    int PermsAvailable = (from up in db.UserPermissions
                          where up.Username == 
                              System.Environment.UserDomainName + "\" + 
                              System.Environment.UserName
                          && up.Publisher == PublisherInput
                          select up).Count();
    if(PermsAvailable)
    {
        var NewBook = New Book with {.Title = TitleInput, .Publisher = PublisherInput};
        db.Books.Add(NewBook);
    }
    
        2
  •  3
  •   Adam Ralph    16 年前

    This article 解释了保护具有特定权限的应用程序的各种方法。为了了解所使用的体系结构,值得阅读本系列的其余部分以及先前的ASP.NET 2.0系列。

        3
  •  1
  •   DOK    16 年前

    从可用性的角度来看,我想知道在用户界面中管理可编辑性是否更友好。作为一个用户,如果我输入数据并收到一条消息,说我没有权限输入,我将不会被鼓励继续参与你的网站。

    如果用户无法向数据库添加任何条目,则可以显示只读页(或DIV)。有权保存新条目的用户将得到一个可编辑的页面/div。

    对于允许保存某些类别信息但不保存其他类别信息的用户,是否可以使用下拉列表限制该类别中的条目?例如,Bob的发布者下拉列表显示MSPress,而Jim的列表包括O'Reilly。这样,他们就可以从这些列表中清楚地看到他们在试图添加数据之前可以做什么。权限不是秘密,对用户是隐藏的。