我有一个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控制器逻辑?