【问题标题】:WCF - How to design service authorization per operation OperationContractWCF - 如何设计每个操作 OperationContract 的服务授权
【发布时间】:2014-07-31 15:30:44
【问题描述】:

我的任务是为现有/旧版 wcf 服务制定授权策略。目前系统中没有授权。基于 Basichttp 的自定义绑定用于处理安全性。 (客户端以加密形式发送用户名/密码,在服务器端,在收到请求后执行数据库检查。此时会在服务器内存中生成一个可过期的令牌并将其放入服务器内存以进行进一步的安全检查)故事的道德,一切以自定义方式实现(未使用 STS、证书等框架的安全特性) 在服务层中,不根据客户端身份进行身份验证检查。理论上,每个客户端只要有一个有效的用户名/密码对,就可以执行每一个操作。

正如我所说,我的任务是在这个遗留系统上实施授权策略。

我对 wcf 比较陌生,我的感觉是身份验证和授权在 wcf 中非常紧密地结合在一起。

似乎有多种选择(http://msdn.microsoft.com/en-us/library/ff648151.aspx),例如:

*使用 ASP.NET 角色管理器进行角色授权,

*使用 SQL Server 角色提供程序进行角色授权, 等等。

我觉得自定义授权策略对我来说是最合适的选择,但自定义示例 http://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx 似乎也将身份验证策略与授权策略混合在一起。在没有任何特殊身份验证策略的情况下,我找不到实现自定义授权的有效示例。您可以猜到,在当前的遗留系统中,安全性是以自定义方式处理的,我无法更改,即我不能使用任何 ws-* 绑定。

我认为可能的解决方案是:

1) 创建一个实现 ParameterInspector 或 MessageInspector 的自定义属性

2) 用这个新的自定义属性装饰所有现有的操作合同

3) 在 BeforeCall 或 AfterReceiveRequest 方法中,应用自定义身份验证逻辑(此自定义逻辑很可能会将用户与角色相关联,并将角色与允许的操作相关联)。

通过抛出异常并在客户端适当地显示消息来拒绝请求。

我的问题是,这种方法有多优雅?考虑到遗留系统的其他限制,还有更优雅的选择吗?我是否遗漏了某些部分,或者 wcf 中的身份验证和授权真的非常紧密耦合?

【问题讨论】:

  • 除了这应该在 CodeReview 上而不是 SO 上,听起来你可以控制它。给予或接受它我会怎么做。研究得很好。

标签: c# .net wcf authentication authorization


【解决方案1】:

在过去,基本上你可以使用声明式编程来装饰每个操作实现,使用 PrincipalPermissionAttribute 和角色名称,然后在 Web.config 中插入 ASP.NET MembershipProvider 和 RoleProvider 等。如果你想要更细粒度的策略控制,您可以编写一些 IAuthorizationPolicy 实现,因为您已经在问题的 MSDN 参考中找到了我们的实现。

因此,即使您有目的的设计可能会奏效,您也会期待更优雅的替代方案。优雅:

  1. 足够的安全性
  2. 最少代码
  3. 应用程序的复杂性最低
  4. 易于进化

这篇文章“Authentication and Authorization with ASP.NET Identity 2.0 for WCF Services”可能会给你一些启发。

还有很多关于使用 Identity 2.0 的原因的文章。

【讨论】:

  • 嗨,安迪,感谢您指出正确的方向:) 实际上,我可以根据示例 [link] leastprivilege.com/2007/08/08/custom-principals-and-wcf) 制作原型。我还想使用声明性的基于角色的安全模型(PrincipalPermissionAttribute 和角色名称)。但是我看到的问题是:1)我想在服务合同接口上管理安全策略,而不是在实际的服务实现中,但这似乎不可能[链接](stackoverflow.com/questions/13517343/…
  • 2) 使用 PrincipalPermissionAttribute link 时,声明式安全策略没有 AND 逻辑,但我们可以接受。您是否有解决方法来在服务接口上应用策略控制。我想要实现的是服务合同中的[PrincipalPermission(SecurityAction.Demand, Role="Admin")] [OperationContract] void MyFunction(string str);。在服务合同中而不是在实际实现中
  • 有充分的理由将合同(接口)与实现分开。虽然不是很频繁,但实际上您可以使用相同的合约进行一些实现。身份验证、授权和策略等是属于实现细节的行为,因此,相应的属性应该在实现中而不是在接口中。
【解决方案2】:

我会完全使用外部授权框架,然后应用MessageInspector。外部化授权架构如下:

外部化授权管理是将业务逻辑与授权逻辑解耦。高效地构建新应用程序非常好,更新旧应用程序时非常好 - 尤其是您可以轻松拦截流的 Web 服务。看看Gartner's report on externalized authorization

对于您手头的问题,我建议您使用XACML,可扩展访问控制标记语言。这是一个 OASIS 标准,为您提供:

  • 一种用于定义基于策略的访问控制授权的策略语言
  • 具有以下概念的灵活架构:
    • 一个策略执行点或 PEP,它拦截您的流并保护您的 WCF 服务。在您的情况下,您应该使用实现 MessageInspector 的 PEP
    • 一个策略决策点或 PDP,它接收来自 PEP 的请求并根据其配置的策略生成决策。
  • 一种请求/响应方案,用于定义 PEP 和 PDP 如何一起交谈。

这是一个勾勒出您想要的系统方式的图表:

如果您需要 .NET PDP,可以从 Axiomatics 获得一份(免责声明:这是我工作的公司)。

HTH

【讨论】:

  • 嗨大卫,实际上这似乎是一个很好的解决方案,将身份验证逻辑与服务逻辑完全解耦。然而,这似乎是一个巨大的部署,需要一些额外的成本:) 你有开源替代方案来外部化授权逻辑吗?谢谢
  • 看看 Apache Shiro 或 Balana。它们不是 .NET,但因为它有一些无关紧要的 API。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2011-04-09
  • 2014-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多