如何保护Web API不受资源所有者的数据检索

Eli*_*eth 15 c# service-layer asp.net-web-api asp.net-web-api2

我有一个asp.net web api.

我想稍后在一个天蓝色的网站上拥有我的Web API.

登录用户可以在浏览器中执行此操作 /api/bankaccounts/3

让所有的细节有关bank account number 3.

但登录的用户不是所有者bank account number 3.

我如何设计我的控制器和记录后面的服务

用户只能在数据库中检索/修改自己的资源?

UPDATE

我创建了一个:

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;
        }
}
Run Code Online (Sandbox Code Playgroud)

问题是现在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();
}
Run Code Online (Sandbox Code Playgroud)

REPO

    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();
    }
Run Code Online (Sandbox Code Playgroud)
  • 对于Get Method,返回错误UserId的任何内容
  • 对于Create Method:没问题,每个人都应该能够在登录时创建资源.
  • 对于更新方法:与Delete方法相同,schoolyear由id和UserId检索.

一般来说,我的存储库中的每个方法都应该考虑CRUD操作中的UserId.

你怎么看?

sno*_*FFF 0

请参阅以下链接 - 它涵盖身份验证(以便您知道谁在请求)和授权(以便您知道他们是否有权查看数据):

http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

添加一些其他细节 - 数据库中定义用户授权的列和/或表是很常见的。身份验证提供程序也有可能提供“声明”或其他信息来定义用户有权访问的内容(取决于您的身份验证机制)。然而,这可能不太安全,因为您确实需要信任此信息的来源,并有办法确保它在提交到您的 api 之前没有被篡改。