私が書いたカスタム Authorization 属性が本当に良いアイデアかどうかを判断しようとしています。
シナリオ
店舗のコレクションがあり、それぞれ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);
}
StoreOwnerAuthorizeAttribute
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;
}
}