![](/img/trans.png)
[英]How to return data from two tables in one resource with Web API, MVC5 via Repository
[英]How to protect a Web API from data retrieval not from the resource owner
我有一個asp.net Web API。
我想稍后在一個蔚藍的網站上自托管我的Web API。
登錄的用戶可以在瀏覽器/api/bankaccounts/3
執行此操作
獲取有關bank account number 3
所有詳細信息 bank account number 3
。
但是登錄的用戶不是bank account number 3
的所有者。
我該如何設計我的控制器以及所記錄的背后的服務
用戶只能在數據庫中檢索/修改自己的資源?
更新
創建完之后:
public class UserActionsAuthorizationFilter : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext != null)
{
bool canUserExecuteAction = IsResourceOwner(actionContext);
// stop propagation
}
}
private bool IsResourceOwner(HttpActionContext actionContext)
{
var principal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var userIdAuthenticated = Convert.ToInt32(principal.Claims.Single(c => c.Type == ClaimTypes.Sid).Value);
int targetId = Convert.ToInt32(actionContext.Request.GetRouteData().Values["Id"]);
var requstScope = actionContext.ControllerContext.Request.GetDependencyScope();
var service = (ISchoolyearService)requstScope.GetService(typeof(ISchoolyearService));
bool canUserExecuteAction = service.HasUserPermission(userIdAuthenticated, targetId);
return canUserExecuteAction;
}
}
現在的問題是IsResouceOwner被硬編碼為某個服務=> SchoolyearService從而綁定到Schoolyear SQL表
我需要保持IsResourceOwner方法通常可用於具有字段UserId / UserEmail的所有sql表。
問題是-我真的認為沒有人會這樣做-我必須將每個資源所有者檢查映射到HasUserPermission方法中的正確Sql表。
該映射應如何顯示?
檢查控制器名稱“ SchoolyearController”,因此要檢查的表是“ schoolyear”表? 這是荒謬的。
此自定義屬性“ UserActionsAuthorizationFilter”將位於每個“數據”控制器上。
在我必須檢查他是否是資源所有者之前,無論用戶觸發了哪個控制器URL來獲取數據。
我想我無法在過濾器中決定這一點。
我必須讓數據檢索/修改通過控制器,並在數據檢索完成之前在存儲庫中進行ResourceOwner檢查。
你覺得這怎么樣:
API
public async Task<IHttpActionResult> Delete(int id)
{
var result = await service.Delete(id, User.Identity.UserId);
if (result == 0)
return NotFound();
return Ok();
}
回購
public async Task<int> Delete(int id, int userId)
{
var schoolyerToDelete = await context.Schoolyears.SingleOrDefaultAsync(s => s.Id == id && s.UserId == userId);
// If schoolyearToDelete is null nothing is removed, thus the affected rows are ZERO.
context.Schoolyears.Remove(schoolyerToDelete);
return await context.SaveChangesAsync();
}
通常來說,我的存儲庫中的每個方法都應在CRUD操作中考慮UserId。
你怎么看?
請參閱以下鏈接-它涵蓋了身份驗證(因此您知道誰在請求)和授權(因此您知道他們是否有權查看數據):
http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
要添加其他細節-數據庫中具有定義用戶授權的列和/或表是很常見的。 取決於您的身份驗證機制,身份驗證提供程序也可能會提供“聲明”或其他信息,這些信息定義了用戶有權訪問的內容。 但是,這可能不太安全,因為您確實需要信任此信息的來源,並有一種方法可以確保在將其提交給您的api之前沒有被篡改。
這是一個古老的問題,但是對於遇到類似問題的任何人,這都是一個可能的解決方案。
public interface IService {
HasUserPermission(int32 userIdAuthenticated, int targetId));}
public interface ISchoolyearService : IService {
/* Include all other methods except for HasUserPermission */
}
從
var service = (ISchoolyearService)requstScope.GetService(typeof(ISchoolyearService));
至
var service = (IService)requstScope.GetService(this.ServiceProvider);
- Then, change all the attributes on your Controllers to specify which type of IService they use
[UserActionsAuthorizationFilter(ServiceProvider = typeof(ISchoolyearService))] <br> internal SchoolyearController : Controller { }
這種方法的顯着缺點是,如果用戶通過了HasUserPermission()
檢查,則將只允許用戶訪問資源,因此,這種方式將禁止您創建應公開訪問的更深層的URL,例如/api/testresults/3/public
PS>您是對的,根據控制器名稱確定要檢查哪個SQL表是很荒謬的😊
我同意在存儲庫中這樣做。 在每個記錄都有一個所有者並且只允許所有者修改或刪除該記錄的情況下,我通常這樣做。
因此,每個記錄都需要使用所有者的外鍵來存儲。
另外,由於您說允許單個用戶而不是一組用戶修改其數據,因此不能通過 授權和角色分配來處理它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.