保护多租户Web API应用程序中的数据访问

时间:2015-10-30 12:03:05

标签: odata asp.net-web-api2 multi-tenant

我有一个Web API 2.2应用程序,我一直在努力,我试图确保跨租户的数据访问。

为简单起见,我使用可重用的where子句锁定对实体的访问权限,该子句使用了用户的身份验证令牌,然后过滤了他们的结果:

// GET: odata/Contacts
    [Queryable]
    public IQueryable<Contact> GetContacts()
    {
        return db.Contacts.Where(_appContext.Helper.Expr_AppContactsFilter);
    }

然后,我能够做同样的事情来覆盖导航属性如何工作如下:

// GET: odata/Contacts(5)/Owner
    [Queryable]
    public IQueryable<Contact> GetOwner([FromODataUri] int key)
    {
        return db.Contacts.Where(m => m.ID == key).Where(_appContext.Helper.Expr_AppContactsFilter).SelectMany(m => m.OwnerContacts);
    }

这样当执行此查询时(... / odata / Contacts(2)/ Owner)结果为空,应该是:

{ "odata.metadata":".../odata/$metadata#Contacts","value":[ ] }

但是,如果我尝试使用所有者属性扩展我可以访问的联系人列表,或者使事情变得更复杂,并从另一个实体导航到联系人,然后导航到所有者,我就可以访问一个可能不属于我租约的实体:

通过Contacts()访问 - / odata / Contacts?$ expand = Owner

{  
   "odata.metadata":".../odata/$metadata#Contacts",
   "value":[  
      {  
         "Owner":{  
            "ID":4,
            ...
            "Application_ID":2 //here we see the owner is not part of this tenant
         },
         "ID":2,
         "Owner_ID":4,
         "Application_ID":1,
        ...
      },
      {  
         "Owner":{  
            "ID":1,
            "FirstName":"System",
            "Application_ID":null, //here we see the owner is not part of this tenant
            ...
         },
         "ID":3,
         "FirstName":"Bruce",
         "Owner_ID":1,
         "Application_ID":1,
      }
   ]
}

并通过2级导航 - ... / odata /网站(2)?$ expand =联系人/所有者

{  
   "odata.metadata":".../odata/$metadata#Websites/@Element",
   "Contact":{  
      "Owner":{  
         ...
         "Application_ID":2,  //here we see the owner is not a part of this tenant
      },
      "ID":2,
      "FirstName":"Shawn",
      "MiddleName":"",
      "LastName":"Souto",
      "Organization":"SSI Design",
      "Owner_ID":4,
      ...
   },
   "ID":2,
   "URL":"http://www.example.com",
    ...
}

有没有办法过滤$ expand逻辑或其他odata参数以保持租户内的访问权限?

另外,有没有更好的方法来做到这一点(这仍然相对简单),而不是完全重做所有的API控制器逻辑?

0 个答案:

没有答案