我已经实现了Service类,让我们说“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故事并不是那么糟糕......
答案 0 :(得分:0)
我想说这一切都取决于你想要如何设计你的API,我认为如果你希望你的API是公开的,那么在你的授权上下文中模糊“过滤器”(比如在你的声明中)并不是一个好主意。对于来电者而言,如果我不得不打电话给您的服务,我必须确切地知道您对来电者的期望是什么类型。
但是,如果您的所有来电者都知道您使用的是基于声明的授权,那么您可以将您的方法设计为“要求”某些声明,那么您的方法就可以了。你可以使用类似的东西:
[PrincipalPermission(SecurityAction.Demand, Role = ManagersWithInventory)]
请记住,如果来电者不具备此特定声明,他将无法调用该方法。所以这可能是所希望的行为。
在一个非常简单的例子中,我只是设计一个带有明确的“过滤器”的服务调用,如
MyService.GetInventoryByReferenceId(string Id)
该合同使调用非常直观,并且调用者有责任决定如何填充过滤器。
修改强> 的
好吧,我不是说你的实现IDispatchMessageInspector是错误的,但可能有点过分,因为你不必要地“嗅探”数据,但你必须进行另一次外部往返以获得调用者的身份。我认为更好的方法是使用“真实”声明身份:双方使用Microsoft.IdentityModel.dll并使用声明透明地让WCF使用它传输凭据。
有一点需要注意的是,您的旧桌面应用程序调用您的服务仍然可以工作,因为WIF将以前的IIdentity包装在IClaimsIdentity中,因此您甚至可以使用或不使用声明的“用户”(在您的服务端)< / p>
希望它有所帮助,
答案 1 :(得分:0)
更新/解决方案?:
经过一番思考和Jorge Alvarado的评论。我决定实施以下内容。所以... Service类不了解安全上下文。 它确实知道有一个属性(枚举)“CompanyName”。 对于实例:
public ClientEnumerationType? CurrentClient { get; set; }
当我服务想要从ReadInventory函数返回结果时,我有以下代码:
IEnumerable<string> ReadAllInventoryItems()
{
var items = ReadAll();
return CurrentClient.HasValue ? FilterByClient(items, urrentClient.Value).ToList() : items;
}
因此,该实现允许我在WCF之外使用该类而没有任何问题。
WCF怎么样? 我正在考虑从WCF到底需要什么,实际上我只需要一件事。授权客户端,实例化服务类并设置值CurrentClient属性。
为了实现这一点,我实施了几项。
1)IEndpointBehavior
我需要它为每个合约方法安装Message Inspector和InstanceProvider以及ParameterInspectors。
2)IDispatchMessageInspector
获取WCF消息,从请求中提取令牌,验证令牌并将Thread.CurrentPrincipal设置为来自请求的所有声明值的ClaimsPrincipal。
第3)IParameterInspector 强>
我需要它来验证合同中每个方法的Claim = Action。 对于实例我有:
[OperationContract]
[ClaimActionRequred(Action = "read")]
IEnumerable<string> ReadAllInventoryItems()
这意味着I Identity Provider应为客户端令牌提供Action声明。 在进行实际调用之前,正在IParameterInspector中分析该声明值。
4)最后一块 - IInstanceProvider
我需要的是,实例化ServiceClass并根据声明值传递CurrentClient属性值。
完成。
我不确定我做得对。但这是我已经做过的事情。