我正在尝试确定我编写的自定义授权属性是否确实是一个好主意。
Scenario
假设我们有一系列商店,每个商店Store
有一个主人。只有商店的所有者才能对商店进行CRUD操作。除了具有Claim
这基本上超越了所有权要求,并表示他们可以在任何商店上进行 CRUD 操作。
旁注:我正在使用 Thinktecture 和 ADFS
所以我做了一个StoreOwnerAuthorize
属性 who 的参数("Manage", "Stores")
用于检查用户是否有适当的声明来“覆盖”不是所有者但仍然能够通过授权检查。
我不确定对于拥有“ManageStores”之类的声明并在属性内进行数据库调用有何感受。这让我觉得我走错了路,尽管它确实实现了我所需要的。
API 路由
api/v1/Store/{storeId:int:min(1)}/employees
api/v1/Store/{storeId:int:min(1)}/inventory
接口方法
[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;
}
}