#security #asp.net-mvc-3 #model-view-controller
#Безопасность #asp.net-mvc-3 #модель-представление-контроллер
Вопрос:
У меня есть структура базы данных, похожая на следующую:
User
----
Id
Name
UserCustomerLink
----------------
UserId
CustomerId
Customer
--------
Id
Name
Address
-------
Id
CustomerId
Address1
Invoice
-------
Id
AddressId
Number
Это asp.net сайт mvc, чтобы пользователь мог перейти по адресу, подобному http://localhost/invoice/details/1
, который вернет счет с идентификатором 1.
Пользователь должен войти в систему и быть назначен клиенту (через таблицу UserCustomerLink), которому принадлежит счет (через адрес).
Мой вопрос в том, где я должен выполнять проверку того, что пользователь может просматривать счет-фактуру?
Должен ли я проверить, что счет существует, и пользователь может просмотреть его, а затем вернуть из базы данных, или я должен извлечь элемент из базы данных, а затем проверить?
Меня беспокоит количество запросов к базе данных, которые будут выполнены для поиска этой информации, и я ищу эффективный метод. Это упрощенный взгляд на структуру, и некоторые дочерние свойства имеют глубину более 3.
В примечании к сайту я сначала использую код Entity Framework, поэтому, если есть способ создать сопоставление, которое включает идентификатор клиента в объект Invoice, это может потенциально решить эту проблему.
Ответ №1:
Нет причин совершать два обращения к базе данных. Вы можете использовать объединения и выполнять один select. Все ваши таблицы имеют внешние ключи, которые связывают записи. Когда запрос возвращается, вы проверяете, связан ли пользователь с этим счетом. Вы могли бы сделать то же самое с LINQ
SELECT
i.*,
c.Name
FROM
INVOICE i JOIN
Address a JOIN
on i.addressId = a.id
Customer c JOIN
on a.customerID = c.id
UserCustomerLink ucl join
on c.id = ucl.CustomerId
User u
on ucl.Userid = User.id
WHERE
i.Id = @invoiceId
Комментарии:
1. Это то, что я в конечном итоге сделал, просто подумал, есть ли «более аккуратный» способ, который не требует такого количества объединений, но, кажется, выполняется достаточно быстро.
Ответ №2:
Посмотрите на атрибут авторизации. Вы могли бы распределить своих пользователей по ролям, а затем позволить фреймворку проверять за вас.
[Authorize(Roles="AllowedUser")]
public ViewResult GetInvoies()
{
return View();
}
Комментарии:
1. То, что вы описываете, — это безопасность на основе ролей, которой это не является. Поскольку пользователь может иметь доступ более чем к одному объекту, дело не в ролях, а в правах доступа, которые различаются у каждого пользователя.