.net 使用RESTful WCF的用户/通过身份验证&;Windows窗体

.net 使用RESTful WCF的用户/通过身份验证&;Windows窗体,.net,wcf,restful-authentication,ws-security,.net,Wcf,Restful Authentication,Ws Security,为与IIS托管的RESTful WCF服务对话的Windows窗体应用程序实现授权/身份验证的最佳方法是什么 我问的原因是我很困惑,在筛选了不同的文章和帖子后,表达了不同的方法,最终找到了一个关于WCF安全最佳实践的650页文档“()考虑到我的场景,我不确定哪种方法是最好的,以及如何开始实施 我从这篇文章“使用WCF 3.5设计和构建RESTful Web服务指南”(Guide to Design and Building to RESTful Web Services with WCF 3.5

为与IIS托管的RESTful WCF服务对话的Windows窗体应用程序实现授权/身份验证的最佳方法是什么

我问的原因是我很困惑,在筛选了不同的文章和帖子后,表达了不同的方法,最终找到了一个关于WCF安全最佳实践的650页文档“()考虑到我的场景,我不确定哪种方法是最好的,以及如何开始实施

我从这篇文章“使用WCF 3.5设计和构建RESTful Web服务指南”(Guide to Design and Building to RESTful Web Services with WCF 3.5)和一个关于RESTful WCF服务的PDC视频开始,这篇文章很棒,帮助我实现了我的第一个REST友好的WCF服务

服务运行后,我返回实现安全性,请参阅“安全注意事项”(页面下方四分之一处),并尝试按照说明实现HTTP授权头,但我发现代码不完整(请参阅如何从未声明“UserKeys”变量)这就是我试图研究更多如何做到这一点(使用带有“授权”HTTP头的HMAC哈希,但在google上找不到多少?)它让我阅读了其他关于消息级安全性、表单身份验证和自定义验证器的文章,坦率地说,我不确定现在采用哪种方法是最好和最合适的

所以说了这么多(谢谢你一直听到现在!),我想我的主要问题是,

-我应该使用哪个安全实现?

-有没有办法避免在每次WCF呼叫时发送用户名/密码?如果一开始就建立了连接,我不希望发送这些额外的字节,这将在登录后允许进行后续呼叫之前发生。

-如果我使用SSL,我真的应该关心纯文本以外的任何东西吗?

如前所述,.NET 3.5 win forms app,IIS托管的WCF服务,但重要的是我希望任何和所有WCF服务都需要此授权过程(不管它应该是什么,会话、http头或其他),因为我不希望任何人能够从web访问这些服务

我知道上面的帖子很大,但我必须表达我已经走过的路,我需要完成的事情,非常感谢所有的帮助

PS:我也知道这篇文章,如果社区建议我放弃REST for WCF服务,我可以这样做,但是我从这篇文章开始是为了保持任何公共API的一致性

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


嗯,您真的不应该太关注WinForms端,因为WCF端是关键

顺便问一下,你仔细看过这些页面了吗

概念

以及如何

好吧,我对WCF的REST功能没有任何经验,但我在理解中的安全选项的含义方面做了很多努力。正如您所注意到的,在Web上确实缺乏有关WCF的文档,我的REST经验也有限,所以我的回答是有点保留的:

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

如果我使用SSL,我是否真的应该关心纯文本以外的任何东西? 通过SSL进行基本身份验证很好——毕竟,许多现有网站都是这样对用户进行身份验证的。(当你登录亚马逊购物帐户时,他们只是在你通过SSL连接键入用户名和密码时传输用户名和密码。)我理解这篇文章所说的关于安全和字典攻击的内容,但是诸如此类,保持简单,首先让它工作起来。UPS的普通XML API在每次调用时都要求输入用户名和密码,联邦快递的POX API也是如此,PayPal的SOAP API和CyberSource的SOAP API也是如此——对于真实世界的美国来说,这似乎已经足够好了通用电气

有没有办法避免在每次WCF呼叫时发送用户名/密码?如果一开始就建立了连接,我不希望发送这些额外的字节,这将在登录后允许进行后续呼叫之前发生。 这是一个我可以更自信地回答的问题。通常,我们尝试将面向公众的WCF服务设计为无状态。这样,我们的WCF服务很容易扩展;只需在这个问题上投入更多的硬件、更多的服务器和负载平衡器,我们就不必担心粘性会话或在某个地方维护会话状态。所以不要担心这意味着,如果我们想“让用户登录”,那么服务器上就不会发生这种情况

我最终做的是将我的网站视为一个受信任的子系统。它使用预共享的X509证书对WCF服务进行身份验证,如果客户通过表单身份验证登录到该网站,则它将向该服务发送一个客户用户名头;WCF服务上的自定义端点行为将查找是标头,请查看它是否由受信任的子系统安装,然后继续模拟该用户,而无需提供用户密码或根据数据库验证该用户密码

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

不过,简而言之,您必须在每个请求中发送一些东西来识别用户,无论是用户名和密码,只是用户名,还是存储在cookie中的一些散列值。如果是最后一个选项,我想您必须具有某种
Login()
方法或服务上的某些内容,这些内容会发送一个“好的,您很抱歉”
WebChannelFactory<IMemberService> cf = new WebChannelFactory<IMemberService>(
                new Uri(Properties.Settings.Default.MemberServiceEndpoint));
            IMemberService channel = cf.CreateChannel();
            Member m = channel.GetMember("user", "pass");
 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" };
    }
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);