我已经实现了服务类,比方说“DataSourceService”。现在我想通过 WCF 公开它并使其成为 REST。没有问题,这可以在 WCF 中轻松完成。
但我想说,架构问题来了。
假设我有一个方法:
IEnumerable<string> ReadAllInventoryItems()
我必须返回的问题 IEnumerable<string>
取决于用户授权声明(角色或权限等)。
我可以通过在 DataSourceService 的每个方法中验证这些声明来做到这一点。
类似的东西:
IEnumerable<string> ReadAllInventoryItems()
{
var companyName = ReadCompanyNameFromAuthorisationContext();
var items = ReadAll().Where( i => i.CompanyName == companyName).ToList();
return Items;
}
我会说这种方法存在一个大问题。 即:如果没有此“声明”上下文,DataSourceService 将变得不可用。 当我在没有 WCF 的情况下使用它时,我必须为每个调用准备 Claims 或 UserIdentity 上下文。
所以我的下一步是“考虑 WCF IDispatchMessageInspector”,但后来我意识到我必须实现一个 IDispatchMessageInspector 和一个 OperationInvoker 然后我可以用某种带有权限的属性来装饰 Web 服务方法(这个属性将被使用稍后在 OperationInvoker 中)。
最后我会得到:
[AuthorizationFiltering]
IEnumerable<string> ReadAllInventoryItems()
{
var items = ReadAll().Where( i => i.CompanyName == companyName).ToList();
return Items;
}
你怎么看?
我应该坚持“在 DataSourceService 的每个方法中验证这些声明”吗? 或 WCF IDispatchMessageInspector,MethodInvoker 的故事还不错......
最佳答案
我想说这完全取决于你想如何设计你的 API,我认为如果你希望你的 API 是公开的并且在你的授权上下文中隐藏一个“过滤器”(比如在你的声明中)并不是一个好主意对于调用者来说很直观,如果我必须调用您的服务,我必须准确地知道您希望调用者提出什么样的 claim 。
但是,如果您的所有调用者都知道您正在使用基于声明的授权,您可以设计您的方法以“要求”某些声明,那么您的方法就很好。你可以使用例如类似的东西:
[PrincipalPermission(SecurityAction.Demand, Role = ManagersWithInventory)]
但请记住,如果调用者不拥有此特定声明,他将无法调用该方法。所以这可能是所需的行为,也可能不是。
在一个非常简单的情况下,我只需要设计一个带有显式“过滤器”的服务调用,例如
MyService.GetInventoryByReferenceId(string Id)
该协定使调用非常直观,调用者有责任决定如何填充过滤器。
编辑
好的,我并不是说您实现的 IDispatchMessageInspector 是错误的,但可能有点矫枉过正,因为您不必要地“嗅探”数据,但您必须进行另一次外部往返才能获得调用者的身份。
我认为更好的方法是在双方都使用“真实”声明身份:Microsoft.IdentityModel.dll 并透明地处理声明,让 WCF 使用它传输凭据。
需要注意的一件事是,调用您的服务的旧桌面应用程序仍然可以工作,因为 WIF 将以前的 IIdentity 包装在 IClaimsIdentity 中,因此您甚至可以在有或没有声明的情况下与您的“用户”一起工作(在您的服务端)
希望对你有帮助
关于c# - DataContext 根据授权声明而变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13472992/