Разрешения SQL для добавления данных и как проверить? - PullRequest
1 голос
/ 07 июня 2009

Я ищу хороший способ сохранить права на добавление данных в базу данных в приложении C # и SQL Server 2005.

Мне нужно объяснить, хотя, чтобы прояснить это. Итак, давайте возьмем пример этого:

У меня есть два пользователя Bob и Jim, оба были добавлены в разрешения SQL, чтобы у них был доступ на запись в базу данных. Теперь весь доступ основан на учетных записях пользователей домена. Все остальные пользователи имеют доступ только для чтения.

Теперь у меня есть пара таблиц, таких как:

  • Пользователи
  • UserPermissions
  • Книга
  • BookPublishers

Итак, UserPermissions содержит список пользователей и книгоиздателей. Так, например: Bob имеет разрешение на добавление книг для MS Press, а Jim имеет разрешение на добавление книг для O'Reilly.

Теперь мне нужно проверить эту информацию и ограничить то, что они могут добавить.

Так сказать, Jim использует мое приложение из командной строки, и он пишет что-то вроде:

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

Инструмент должен пойти дальше и добавить книгу в таблицу книг.

Теперь, скажем, Bob пробует ту же команду, инструмент должен выдать ошибку, поскольку у него нет разрешения на добавление книг по O'Reilly.

Прямо сейчас мне нужно знать, как сделать пару вещей.

  • Убедитесь, что у пользователя сначала есть разрешение на запись на SQL Server
  • Убедитесь, что у пользователя есть разрешение на запись для добавления books конкретным издателем
  • Кроме того, мне нужно убедиться, что вышеприведенное верно, прежде чем инструмент действительно попытается добавить данные, т. Е. Прежде чем инструмент продолжит работу, мне нужно получить подтверждение о проверке

Теперь я не на 100% беспокоюсь о том, что пользователь вводит вредоносные данные, хотя было бы неплохо это остановить, но это внутренний инструмент, и я полагаю, что могу доверять пользователям ... (возможно)

В любом случае, я не знаю, с чего начать, моим навыкам SQL очень не хватает.

Akk, последнее, я не хочу добавлять данные с использованием процедур хранилища.

Ответы [ 3 ]

5 голосов
/ 07 июня 2009

Хорошо, давайте разберемся с этим:

Убедитесь, что пользователь может записать в таблицу (это вернет 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);
}
3 голосов
/ 07 июня 2009

Эта статья содержит объяснение различных методов защиты приложений с определенными разрешениями. Чтобы понять используемую архитектуру, стоит прочесть остальную часть серии, а также предыдущие серии ASP.NET 2.0.

1 голос
/ 07 июня 2009

С точки зрения удобства использования, мне интересно, не будет ли удобнее управлять возможностью редактирования в пользовательском интерфейсе. Как пользователь, если я введу данные и получу сообщение о том, что у меня нет разрешения на эту запись, меня не призовут продолжать участвовать в вашем веб-сайте.

Если пользователь не может добавить какие-либо записи в базу данных, вы можете отобразить страницу только для чтения (или DIV). Пользователи с разрешениями на сохранение новых записей получат редактируемую страницу / DIV.

Для пользователя, которому разрешено сохранять некоторые категории информации, но не другие, будет ли работать ограничение количества записей в этой категории с помощью раскрывающегося списка? Например, в раскрывающемся списке Боба издателя отображается MSPress, а в списке Джима - О'Рейли. Таким образом, они могут ясно видеть из этих списков, что им разрешено делать, прежде чем они попытаются добавить данные. Разрешения не являются секретом, скрыты от пользователя.

...