Буду признателен за некоторые указания относительно доступа к данным и управления ими на мультитенантном сайте на основе MVC:
Существует ли лучший / более безопасный / элегантный способ убедиться, что на мультитенантном сайте пользователь может обрабатыватьтолько свои данные.Существует несколько арендаторов, использующих одно и то же приложение: firstTenant.myapp.com, secondTenant.myapp.com ...
//
// GET: /Customer/
// show this tenant's customer info only
public ViewResult Index()
{
//get TenantID from on server cache
int TenantID = Convert.ToInt16( new AppSettings()["TenantID"]);
return View(context.Customers.ToList().Where(c => c.TenantID == TenantID));
}
Если пользователь входит в систему в первый раз и для этого нет кэша на стороне сервераtenant / user - AppSettings проверяет в дБ и сохраняет TenantID в кеше.
Каждая таблица в базе данных содержит поле TenantID и используется для ограничения доступа к данным только соответствующему арендатору.
Итак,вместо того, чтобы проверять каждое действие в каждом контроллере, если данные принадлежат текущему арендатору, могу ли я сделать что-то более «продуктивное»?
Пример:
Когда администратор firstTenant пытается редактироватьнекоторая информация для пользователя 4, URL имеет: http://firstTenant.myapp.com/User/Edit/4
Предположим, что пользователь с идентификатором 2 принадлежит secondTenant.Администратор из firstTenant помещает http://firstTenant.myapp.com/User/Edit/2 в URL и пытается получить информацию, которая не принадлежит его компании.
Чтобы предотвратить это в контроллере, я проверяю, действительно ли редактируемая информация принадлежиттекущий арендатор.
//
// GET: /User/Edit/
public ActionResult Edit(int id)
{
//set tennant ID
int TenanatID = Convert.ToInt32(new AppSettings()["TenantID"]);
//check if asked info is actually owned by this tennant
User user = context.Userss.Where(u => u.TenantID == TenantID).SingleOrDefault(u => u.UserID == id);
//in case this tenant doesn't have this user ID, ie.e returned User == null
//something is wrong, so handle bad request
//
return View(user);
}
По сути, этот вид установок необходимо размещать в каждом контроллере, где есть доступ к любым данным.Есть ли (и как) лучший способ справиться с этим?(Фильтры, атрибуты ...)