用户/通过使用RESTful WCF和Windows窗体的身份validation

为Windows Forms应用程序与IIS托pipe的RESTful WCF服务交谈实施授权/身份validation的最佳方法是什么?

我问的原因是我很困惑,筛选了不同的文章和职位expression不同的方法,并最终在WCF安全最佳实践“( http://www.codeplex.com/WCFSecurityGuide )上达到约650页的文档我是根据我的情况,只是不确定哪种方法是最好的,以及如何开始实施。

我从本文开始使用“使用WCF 3.5devise和构buildREST风格的Web服务”( http://msdn.microsoft.com/zh-cn/library/dd203052.aspx )以及REST风格的WCF服务上的PDCvideo。很棒,帮助我实现了我的第一个REST友好的WCF服务,

我有了服务工作后,我回到了实施安全,见。 “安全注意事项”(页面上的四分之一),并试图按照说明实现一个HTTP授权标头,但是我发现代码是不完整的(请参阅UserKeysvariables从未声明)。 这是我试图研究更多关于如何做到这一点(使用HMAC哈希与“授权”HTTP标头,但在谷歌上找不到多less?),这导致我到其他文章有关消息级别的安全性,形成authentication和自定义validation器,坦率地说,我不确定哪个是现在采取的最好和最合适的方法。

所以所有这些(并感谢听到直到现在!),我想我的主要问题是,

– 我应该使用哪种安全实施?

– 有没有办法避免每个WCF调用发送用户名/密码? 如果在开始时已经build立了一个连接,我宁愿不发送这些额外的字节,这将在login之后允许进行后续的呼叫。

– 如果我使用SSL,是否真的应该关心纯文本?

如上所述,.NET 3.5 win表单应用程序,IIS托pipe的WCF服务,但是重要的是我希望任何和所有的WCF服务都需要这个授权过程(不过它应该是会话,http头或其他),因为我不希望任何人都能够从networking上获得这些服务。

我知道上面的post很大,但我不得不expression我已经倒闭的路线,我需要完成的任何和所有的帮助,我非常感激。

PS:我也知道这篇文章如何使用WCF使用用户名/密码+ SSLconfiguration安全的REST风格的服务,如果社区build议我离开REST的WCF服务,我可以做到这一点,但是我开始保持一致任何公共的API来。

我认为这是很重要的,我说我如何访问我的WCF服务(联系服务正在工作,但什么是validation凭据 – 然后返回成员对象的最佳方式?

WebChannelFactory<IMemberService> cf = new WebChannelFactory<IMemberService>( new Uri(Properties.Settings.Default.MemberServiceEndpoint)); IMemberService channel = cf.CreateChannel(); Member m = channel.GetMember("user", "pass"); 

从MS文章(和我自己的一些testing)实施的一半代码:

  public Member GetMember(string username, string password) { if (string.IsNullOrEmpty(username)) throw new WebProtocolException(HttpStatusCode.BadRequest, "Username must be provided.", null); if (string.IsNullOrEmpty(password)) throw new WebProtocolException(HttpStatusCode.BadRequest, "Password must be provided.", null); if (!AuthenticateMember(username)) { WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized; return null; } return new Member() { Username = "goneale" }; } 

那么,我对WCF的RESTfunction没有任何经验,但是我在WCF安全问题中理解了安全select的含义,并且做了很多努力。 正如你已经注意到的那样,WCF在Web上实际上缺乏文档,而且我的REST经验也是有限的,所以用我的答案来解答一下:

我应该使用哪种安全性实现?

如果我使用SSL,是否真的应该关心纯文本?

毕竟,基于SSL的基本身份validation没有问题,因为大量的现有网站对用户进行身份validation。 (当你login你的亚马逊购物账户,他们只是通过SSL连接input你的用户名和密码。)我明白这篇文章是关于安全和字典攻击的说法,但等等等等,保持简单先做些事情 UPS的Plain Old XML API在每次调用时都要求input用户名和密码,FedEx的POX API也是如此,PayPal的SOAP API和Cyber​​Source的SOAP API也是如此 – 这对于真实世界的使用似乎已经足够了。

有没有办法避免每个WCF调用发送用户名/密码? 如果在开始时已经build立连接,我不希望发送这些额外的字节,在login后允许进行后续的呼叫之前。

这是我可以更自信地回答一个。 通常,我们试图将我们面向公众的WCF服务devise为无状态。 这样,我们的WCF服务就可以轻松扩展。 只是抛出更多的硬件和更多的服务器和负载平衡器的问题,我们不必担心粘滞的会话或维护会话状态的地方。 这意味着如果我们想“保持用户login”,那么服务器上就不会发生这种情况。

我最终做的是把我的网站当作一个可信的子系统。 它使用预先共享的X509证书针对WCF服务进行身份validation,如果客户通过表单身份validationlogin到Web站点,则会向服务发送客户用户名头; WCF服务上的自定义端点行为将查找此标头,请参阅它是由受信任的子系统安装的,然后继续模拟该用户,而不需要根据数据库提供或validation用户的密码。

由于您使用的是REST,因此您可以在客户端使用cookie来维护状态。 如果您使用ASP.NET兼容模式,我认为您甚至可以直接使用Forms身份validation,但是我不太了解这种方法,因为我的WCF服务不是IIS托pipe的。

简而言之,您将不得不发送每个请求来标识用户,无论是用户名和密码,只是用户名,还是存储在cookie中的一些哈希值。 如果最后一个选项,我猜你必须有某种Login()方法或某种服务上的东西,会发送一个“好的,你会logging,如果你传递这个散列值与未来的请求。 但并不是所有的REST客户端都会期待接收cookie,只是简单的GET / PUT / POST / DELETE请求而没有任何状态。

如果那些是我的鞋子,我会去受信任的子系统方法(其中一个用户名头提供与子系统的预先共享的凭据),或者我需要在每个呼叫的身份validation。 如果所有这些重复请求成为问题,服务可能会得到一些高性能的身份validationcaching机制。

希望有一点帮助。

使用基本authentication:

 WebHttpBinding binding = new WebHttpBinding(); binding.SendTimeout = TimeSpan.FromSeconds(25); binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly; binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; Uri address = new Uri("http://localhost:3525/WcfRestWeb/Quotes.svc"); WebChannelFactory<IQuoteService> factory = new WebChannelFactory<IQuoteService>(binding, address); factory.Credentials.UserName.UserName = "tan"; factory.Credentials.UserName.Password = "wani"; IQuoteService proxy = factory.CreateChannel(); var response = proxy.GenerateQuote(GetQuoteRequest()); Console.WriteLine("Quote Amount: " + response.QuoteAmount); 

感谢您的答案。 在整个问题上退后一步,看上去没有偏见(换句话说,忽略了我投入的4个多小时来研究REST风格的服务),我试图在没有REST的情况下使用这个工具,以及我正在尝试使用的引用现在是这些:

这似乎适用于我想要的。

lextm:我在这里听到你的消息后,我写了一篇文章,通过WCF安全指南进行了更仔细的扫描,并根据他们希望您在每个信条上思考的选项提出了我所有要求的注释。

我已经select:
– 传输安全模式:传输安全
– validation 选项:基本安全
– 绑定:wsHttpBinding
– 使用用户名validation器进行自定义validation

根据为每个提供的例子,看看Windows窗体W / WCF服务的用例,这似乎是最好的方式去。

Nicholas:同意,将服务devise为无状态可能是更好的方法。

所以基于这篇文章,我会在获得时间后继续使用X509证书。 这是我很新的(理解你使用这个尼古拉斯)这将是正常的,因为这个客户端应用程序可以从互联网上下载并安装在任何人的个人电脑谁拥有我的网站帐户?

欢呼你的帮助,格雷厄姆

PS: 我认为这是对我的情况最接近的用例 (除了我希望使用传输安全性),我是否应该考虑实现这一点,因为它不打扰证书? 从我读的报价我可能需要证书。 因为“WCF需要X509证书encryption,因为客户端证书(用户名/密码)在SOAP消息中以明文forms传递。 – 但是从我学到的和我们所说的,如果我使用SSL,这一点可能是没有意义的?