[英]asp.net webapi dynamic authorization
我是 webapi 和 mvc 的新手,我正在努力尋找基於角色和資源所有權動態處理授權的最佳實踐。 例如,應允許員工管理員、員工呼叫中心或擁有客戶的帳戶頁面獲取、發布、放置或刪除帳戶信息。 因此,管理員和呼叫中心員工應該能夠獲取、發布、放置或刪除對任何用戶 ID 的任何請求,但客戶端應該只能對他們擁有的資源執行這些操作。
例如,Tom 是 UserID 10,Jerry 是 UserID 20。
/api/Account/10 應該可以被任何管理員、呼叫中心或 Tom 訪問。 傑瑞應該被踢出去。 /api/Account/20 應該可以被任何管理員、呼叫中心或 Jerry 訪問。 湯姆應該被踢出去。
在 webforms 中,典型的解決方案是檢查用戶是否是客戶端並根據請求驗證他們的 id。 (我知道 AuthorizeAttribute 不在 webforms 中,但作為一個例子顯示了它在 webapi/mvc 中的隱藏內容。)
[Authorize(Roles = "Administrator, CallCenter, Client")]
public string Get(int userID)
{
if (Thread.CurrentPrincipal.IsInRole("Client") && Thread.CurrentPrincipal.Identity.userID != userID)
{
//Kick them out of here.
}
return "value";
}
這會起作用,但似乎所有權檢查應該在到達控制器之前在單個位置進行,並且應該可以在整個應用程序中重復使用。 我猜最好的地方是自定義 AuthorizationFilterAttribute 或自定義 AuthorizeAttribute,並且可能創建一個新角色 ClientOwner。
[Authorize(Roles = "Administrator, CallCenter, ClientOwner")]
public string Get(int userID)
{
return "value";
}
自定義授權屬性
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
//If user is already authenticated don't bother checking the header for credentials
if (Thread.CurrentPrincipal.Identity.IsAuthenticated) { return; }
var authHeader = actionContext.Request.Headers.Authorization;
if (authHeader != null)
{
if (authHeader.Scheme.Equals("basic", StringComparison.OrdinalIgnoreCase) &&
!String.IsNullOrWhiteSpace(authHeader.Parameter))
{
var credArray = GetCredentials(authHeader);
var userName = credArray[0];
var password = credArray[1];
//Add Authentication
if (true)
{
var currentPrincipal = new GenericPrincipal(new GenericIdentity(userName), null);
var user = GetUser(userName);
foreach (var claim in user.Cliams)
{
currentPrincipal.Identities.FirstOrDefault().AddClaim(new Claim(ClaimTypes.Role, claim);
}
//**************Not sure best way to get UserID below from url.***********************
if (user.userTypeID = UserTypeID.Client && user.userID == UserID)
{
currentPrincipal.Identities.FirstOrDefault().AddClaim(new Claim(ClaimTypes.Role, "ClientOwner"));
}
Thread.CurrentPrincipal = currentPrincipal;
return;
}
}
}
HandleUnauthorizedRequest(actionContext);
}}
有人可以指出我處理個人用戶授權的最佳位置的正確方向嗎? 這仍然應該在控制器中完成還是應該將它移動到自定義 AuthorizationFilterAttribute 或自定義 AuthorizationAttribute 或者是否應該在其他地方處理? 如果正確的位置在自定義屬性中,那么獲取用戶 ID 的最佳方法是什么,我應該像上面的示例一樣創建一個新角色還是應該做一些不同的事情?
這是一個常見的場景,我很驚訝我一直在努力尋找上述場景的例子。 這讓我相信要么每個人都在控制器中進行檢查,要么還有另一個我不知道的術語,所以我沒有得到好的谷歌結果。
我認為您可能對授權和權限感到困惑。 “動態授權”不是你做過的事情。
授權是驗證作者的行為。
權限是指定誰可以在您的系統中做什么的業務邏輯。
內置的[Authorize]
屬性讓您可以選擇指定允許訪問資源的Roles
。 在我看來,將權限指定為授權的一部分的選項有點錯位。
我的建議是讓授權純粹是驗證請求作者的過程。 這里描述的BasicAuthHttpModule
已經接近你想要的了。
非平凡的權限邏輯需要在您的操作主體內進行處理。 下面是一個例子:
//Some authorization logic:
// Only let a request enter this action if the author of
// the request has been verified
[Authorize]
[HttpDelete]
[Route("resource/{id}")]
public IHttpActionResult Delete(Guid id)
{
var resourceOwner = GetResourceOwner(id);
//Some permissions logic:
// Only allow deletion of the resource if the
// user is both an admin and the owner.
if (!User.IsInRole("admin") || User.Identity.Name != resourceOwner)
{
return StatusCode(HttpStatusCode.Forbidden);
}
DeleteResource(id);
return StatusCode(HttpStatusCode.NoContent);
}
在這個例子中,很難將權限邏輯作為操作的屬性來傳達,因為將當前用戶與資源所有者進行比較的權限部分只能在您實際從您的后端存儲設備。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.