1

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

不过,我需要解释清楚。所以让我们举个例子:

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

现在我有几个表,例如:

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

因此UserPermissions包含用户和图书出版商的列表。例如:Bob有权为 . 添加书籍MS PressJim有权为O'Reilly.

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

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

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

该工具应该继续将书添加到书表中。

现在说Bob尝试相同的命令,该工具应该出错,因为他没有权限添加书籍O'Reilly

现在我需要知道如何做几件事。

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

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

无论哪种方式,我都不知道从哪里开始,我的 SQL 技能非常缺乏。

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

4

3 回答 3

6

好的,让我们分解一下:

验证用户是否可以写入表(如果为真则返回 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 解决方案是愚蠢的(至少在计数问题上):

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);
}
于 2009-06-07T18:57:46.513 回答
3

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

于 2009-06-07T18:35:07.103 回答
1

从可用性的角度来看,我想知道在 UI 中管理可编辑性是否更友好。作为用户,如果我输入数据并收到一条我无权进行该条目的消息,我不会被鼓励继续参与您的网站。

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

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

于 2009-06-07T19:02:36.223 回答