您所描述的问题是一个众所周知的问题,至少有两种标准化解决方案。
第一种选择是基于WS-Trust的活动联合的SOAP解决方案。在这个解决方案中:
• 您的客户端向身份验证服务提供凭据。
• 如果凭证有效,则身份验证服务会向客户端返回签名(和加密)的令牌。它被加密以使令牌中包含的任何信息保持机密性,即使客户端也无法读取它。它使用属于您WCF服务的公钥进行加密。它使用身份验证服务拥有的私钥进行签名。
• 客户端将签名/加密的令牌提交给您的WCF服务。该服务可以解密它,因为它持有用于解密的私钥。它可以信任它,因为它由身份验证服务签名。
• 根据解密令牌的内容,服务可以确定客户端身份并做出授权决策。
在这种模型中,通常的术语如下:
• 您的身份验证服务是安全令牌服务。
• 您的WCF服务是受信方。
• 您的客户端是客户端。
这听起来很复杂,但它在.NET和WCF中得到了非常好的支持,使用Windows Identity Foundation。有许多示例可用,其中大部分(也许全部)可以通过WCF配置而不是代码完成。
这非常适合客户端具有密码功能(如您的.NET客户端)并且存在良好框架的情况下(如WIF)。它对于低配客户端(如浏览器和某些手机)或您无法控制客户端的情况则不太适用。
它通常用于企业场景,包括企业对企业联合。在互联网场景中使用较少。
它的优点是:
• 它是标准化的因此一般受到框架的支持。
• 这意味着您的WCF服务永远不必处理客户端凭据(=更安全)。
它使得切换到不同的身份验证服务变得非常容易(因为它是标准化的)。例如,本地 AD 和 Windows Azure AD 都支持此功能,其他独立的身份认证服务也支持。
可以在这里找到概述:
http://msdn.microsoft.com/en-us/magazine/ee335707.aspx
而且谷歌会向您展示更多的演示和例子。
使用 OAuth 2 进行联合
在这个解决方案中:
- 客户端显示身份验证服务提供的一些 UI(通常是一个网页)
- 用户在该 UI 中输入其凭据,并进行身份验证,最终将令牌返回给客户端。 令牌的性质没有标准化,也不清楚是否加密。 通常至少会签名。
- 客户端将每个请求都与令牌一起提交给 WCF 服务
- WCF 服务像前一个解决方案一样对令牌进行身份验证
按照 OAuth 的术语:
- 您的身份验证服务是授权服务器
- 您的 WCF 服务是资源所有者
- 您的客户端是客户端
同样,这听起来很复杂,但在 .Net 中得到了相当好的支持。 现在可能不如 WS-Trust 方法支持得好。 它受到 Windows Azure AD 的支持,在客户端方面使用 Windows Azure 认证库。 其他许多服务也使用此方法 - 例如 Facebook。
以下情况下此方法效果良好:
- 您的客户端低配或没有加密功能(例如,浏览器或某些手机)
- 您不能控制客户端(例如第三方应用正在访问您的服务)
这种标准在互联网应用中非常常见,其中您作为WCF服务的所有者不一定知道用户或客户端。从某些方面来说它是一个不太完整的标准(例如它没有确切地定义认证是如何进行的),因此更难切换到替代的授权服务器。
它的优点包括:
- 它更简单,因此具有更广泛的平台支持
- 它越来越受欢迎,因此库的支持也变得越来越好了
- 用户只需将其凭据输入到身份验证服务器中而不是您的UI中,因此在互联网场景中更可信
- 它内置了一种控制向客户端授予权限范围和撤销这些权限的方式,因此在互联网场景中更可信
官方的.NET支持在Windows Azure AD Authentication库中
http://msdn.microsoft.com/en-us/library/windowsazure/jj573266.aspx
还有其他的开源组件,例如DotNetOpenAuth
http://dotnetopenauth.net/
哪种解决方案最适合您主要取决于身份验证服务的性质,以及是否处于企业或互联网场景中。如果认证服务可以轻松地改为WS-Trust Secure Token Service(STS),那么这将是一个不错的选择。如果向认证服务添加一些Web UI是可行的,则OAuth可能更好。
或者,如果两种选项都不可行,您可以借鉴一种方法并在不采用完整标准的情况下使用它。
祝你好运!