Я пытаюсь решить, действительно ли пользовательский атрибут авторизации, который я написал, является хорошей идеей.
Сценарий
Допустим, у нас есть набор магазинов, у каждого Store
есть владелец. Только владелец магазина может выполнять операции CRUD в магазине. ЗА ИСКЛЮЧЕНИЕМ пользователей с Claim
, который в основном переопределяет требование владения и говорит, что они могут выполнять операции CRUD в ЛЮБОМ магазине.
Примечание: я использую Thinktecture и ADFS.
Поэтому я создал атрибут StoreOwnerAuthorize
, параметры которого ("Manage", "Stores")
используются для проверки того, есть ли у пользователя соответствующее требование «переопределить», не являясь владельцем, но все же способное пройти проверку авторизации.
Я не уверен, как я отношусь к утверждению типа «ManageStores» и вызову базы данных внутри атрибута. Это заставляет меня думать, что я иду по ложному пути, хотя это делает именно то, что мне нужно.
Маршруты API
api/v1/Store/{storeId:int:min(1)}/employees
api/v1/Store/{storeId:int:min(1)}/inventory
Метод API
[StoreOwnerAuthorize("Manage", "Stores")]
[ResourceAuthorize("View", "Store")]
[Route("")]
//api/v1/Store/{storeId:int:min(1)}/employees
public IHttpActionResult GetStoreEmployees(int storeId)
{
return Ok(collectionOfStoreEmployees);
}
Атрибут авторизации владельца магазина
public class StoreOwnerAuthorizeAttribute : ResourceAuthorizeAttribute
{
private readonly DbContext _context = new DbContext();
public StoreOwnerAuthorizeAttribute(){ }
public StoreOwnerAuthorizeAttribute(string action, params string[] resources)
: base(action, resources) { }
protected override bool IsAuthorized(HttpActionContext actionContext)
{
//If the user has the Claim that overrides the requirement that the user
//is the Owner of the Store, skip checking if they are the owner
if (base.IsAuthorized(actionContext))
return true;
//Get route parameter to lookup Store and determine if the user is the owner
object storeId;
actionContext.ControllerContext.RouteData.Values.TryGetValue("storeId", out storeId);
var isOwner = false;
if (storeId != null)
{
isOwner =
_context.Store_Get_ByStoreID(int.Parse(storeId.ToString()))
.Any(x => x.OwnerId == theUser.Id());
}
return isOwner;
}
}