Разрешения SQL для добавления данных и как проверить?
Я ищу хороший способ сохранить разрешения на то, кто может добавлять данные в базу данных в приложении 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 очень не хватает.
Акк, последнее, я не хочу добавлять данные, используя процедуры магазина.
3 ответа
Хорошо, давайте разберемся с этим:
Убедитесь, что пользователь может писать в таблицу (это вернет 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);
}
В этой статье рассказывается о различных способах защиты приложений с определенными разрешениями. Стоит прочитать остальную часть серии, а также предыдущие серии ASP.NET 2.0, чтобы понять используемую архитектуру.
С точки зрения удобства использования, мне интересно, не будет ли удобнее управлять возможностью редактирования в пользовательском интерфейсе. Как пользователь, если я введу данные и получу сообщение о том, что у меня нет разрешения на эту запись, меня не будут поощрять продолжать участвовать в вашем веб-сайте.
Если пользователь не может добавить какие-либо записи в базу данных, вы можете отобразить страницу только для чтения (или DIV). Пользователи с разрешениями на сохранение новых записей получат редактируемую страницу /DIV.
Для пользователя, которому разрешено сохранять некоторые категории информации, но не другие, будет ли работать ограничение количества записей в этой категории с помощью раскрывающегося списка? Например, в выпадающем списке Боба для MSPress отображается MSPress, а в списке Джима - O'Reilly. Таким образом, они могут ясно видеть из этих списков, что им разрешено делать, прежде чем они попытаются добавить данные. Разрешения не секрет, скрытые от пользователя.