我们有一个C#客户端应用程序,它通过WCF与我们的C#后端服务进行通信。我们希望确保对我们的服务进行的每个WCF调用都来自已登录到我们客户端的用户,而不是通过已经找到如何调用我们的WCF服务的黑客。
我想我们有几种方法可以确保这一点。其中之一是让我们的后端Login方法返回某种令牌,每个客户端WCF调用必须作为WCF调用的一部分传递。为了获得这样的令牌,调用者必须提供有效的登录凭证。然后,对于每个WCF调用,令牌将在后面进行验证。如果无法验证令牌,则WCF调用将失败。
我想要一个简单明了的方法。我们不需要任何超级复杂和安全的东西。任何人都有关于实现这一目标的标准方法的任何信息?我们正在使用.NET 4.我应该补充一点,我对WCF没有太多经验。
更多信息。我们有两个不同的客户端应用调用我们的WCF服务。一个是基于WPF的客户端,另一个是基于浏览器的应用程序(ASP.NET)。两者都是互联网应用程序。我们的客户可以在世界任何地方。
答案 0 :(得分:1)
实现此目的的最简单方法是使用wsHttpBinding
进行此配置:
<bindings>
<wsHtttpBinding>
<binding name="securitySession">
<security mode="Message">
<message clientCredentialType="UserName"
establishSecurityContext="true"
negotiateServiceCredentials="false" />
</security>
</binding>
</wsHttpBinding>
</binding>
此绑定使用安全会话配置状态完整服务。如果客户端为服务创建代理,则必须在内部执行的初始安全握手中传递用户名和密码。在此握手期间,WCF创建与安全令牌关联的服务实例。安全令牌传递回客户端代理,代理在内部存储它。来自同一代理实例的任何后续调用都包含此令牌,该令牌对它们进行身份验证并将它们与正确的服务实例配对。
要使此配置在自定义环境中运行,您必须将服务配置为使用可以保护通信的证书(否则任何人都可以拦截通信和钢铁用户名和密码或令牌)。您还必须在服务端使用自定义用户名和密码验证程序(或ASP.NET成员身份)。
它如何适合您的解决方案?
您的ASP.NET应用程序可以使用该服务使用自定义表单身份验证来启动安全会话。在ASP.NET方面,您需要将代理保留在ASP.NET会话中,并且必须正确配置安全性和ASP.NET会话的超时,以便ASP.NET会话在WCF安全会话之前到期。您将使用cookie为后续客户端调用接收正确的ASP.NET会话。
在WPF应用程序中,您可以为每个应用程序运行使用相同的方法和存储代理。您只需确保代理不会超时或处理超时并再次登录用户。客户端计算机还必须信任您的服务使用的证书。
如果是WPF,您还可以避免安全会话,并使用establishSecurityContext="false"
在您的服务上公开第二个端点。在这种情况下,用户名和密码将包含在来自WPF应用程序的每次调用中,并且您不必与使用状态全服务的长期代理相关的许多问题进行斗争。没有安全上下文服务,您的WPF应用程序将更少状态。你不想在ASP.NET中使用它的原因是你必须在会话中存储用户名和密码。
此解决方案有哪些缺点?
这是重量级的解决方案。安全上下文提供了您正在寻找的功能,无需任何编码,但它有自己的成本。您将不得不在ASP.NET应用程序中使用会话来维护WCF代理,您将拥有状态全服务,这是您应该经常避免的,如果您希望应用程序负载过重,则必须进行大量性能和内存调整。您必须控制正确释放的会话以及所有WCF代理都已正确关闭和处理,以便也释放服务实例。您必须在WCF中使用限制来支持足够的并发运行服务实例。
4年前,我在面向网络应用程序的网络应用程序中成功使用了类似的方法,但我们花了一些时间来查找所有问题并正确配置所有超时并正确处理所有对象的发布。
作为替代方案,您可以查找某些联合方案,其中您将拥有一个额外的服务处理身份验证并提供安全令牌,该令牌将用于对ASP.NET应用程序和WCF服务进行身份验证。我认为OAuth也应该处理这种情况。
答案 1 :(得分:0)
我建议你使用wsHttpBinding和基于证书的邮件安全性。 请看一下这里的演练:http://www.codeproject.com/Articles/28248/Securing-WCF-Services-with-Certificates(适用于Windows Server 2003,但在较新的服务器上程序没有太大差别)