当前位置:  开发笔记 > 编程语言 > 正文

使用RESTful WCF和Windows窗体进行用户/通过身份验证

如何解决《使用RESTfulWCF和Windows窗体进行用户/通过身份验证》经验,为你挑选了2个好方法。

对于与IIS托管的RESTful WCF服务进行通信的Windows窗体应用程序,实现授权/身份验证的最佳方法是什么?

我问的原因是我非常困惑,在筛选出不同的文章和帖子后表达了不同的方法并最终在WCF安全最佳实践中找到了约650页的文档"(http://www.codeplex.com/WCFSecurityGuide)我是根据我的情况,我不确定哪种方法最好采取以及如何开始实施.

我从这篇文章"使用WCF 3.5设计和构建RESTful Web服务指南"(http://msdn.microsoft.com/en-us/library/dd203052.aspx)和RESTful WCF服务的PDC视频开始很棒,帮助我实现了我的第一个REST友好的WCF服务,

在我使用该服务后,我返回实施安全性,请参阅."安全注意事项"(页面下方四分之一)并尝试按照说明实现HTTP Authorization标头,但是我发现代码不完整(请参阅"UserKeys"变量从未声明的方式).这是我试图研究如何做到这一点的更多点(使用带有"授权"HTTP标头的HMAC哈希,但在谷歌上找不到多少?)它引导我阅读有关消息级安全性的其他文章,形成auth和自定义验证器,坦率地说,我不确定哪种方法最好,最合适.

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

- 我应该使用哪种安全实施方案?

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

- 如果我使用SSL,我是否真的应该关注除纯文本以外的任何内容?

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

我知道上面的帖子很大但是我必须表达我已经失败的路线以及我需要完成的任务,我们非常感谢所有的帮助.

PS:我也知道这篇文章如何使用用户名/密码+ SSL配置WCF的安全REST服务,如果社区建议我从REST转移到WCF服务,我可以这样做,但是我开始这样做以保持一致性任何公共API来.

我认为重要的是我说明了我如何访问我的WCF服务(联系服务正在运行,但验证凭据的最佳方法是什么 - 然后返回Member对象?):

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

代码是MS文章中的一半(以及我自己的一些用于测试):

 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" };
    }

Nicholas Pia.. 17

好吧,我对WCF的REST功能没有任何经验,但我确实在理解安全选择在WCF安全问题中的含义时遇到了很多困难.正如你所注意到的那样,WCF在Web上的文档确实缺乏,而且我的REST体验有限,所以我的答案很简单:

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

如果我使用SSL,我是否真的应该关注除纯文本以外的任何内容?

通过SSL的基本身份验证很好 - 毕竟,这是大量现有网站对用户进行身份验证的方式.(当您登录亚马逊购物帐户时,他们只是在您通过SSL连接键入时发送您的用户名和密码.)我理解文章中关于安全和字典攻击的内容,但是等等等等,请保持简单并先获得一些工作.UPS的普通旧XML API会在每次调用时询问用户名和密码,FedEx的POX API也是如此,PayPal的SOAP API和Cyber​​Source的SOAP API也是如此 - 这似乎足以满足现实世界的使用需求.

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

这是我可以更自信地回答的问题.通常,我们尝试将面向公众的WCF服务设计为无状态.这样,我们的WCF服务很容易扩展; 只是在问题上抛出更多的硬件和更多的服务器和负载均衡器,我们不必担心粘性会话或在某处维护会话状态.所以这意味着如果我们想"让用户登录",那么服务器上就不会发生这种情况.

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

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

简而言之,您将不得不通过每个请求发送一些内容来识别用户,无论是用户名和密码,只是用户名,还是存储在cookie中的一些散列值.如果是最后一个选项,我猜你必须在服务上有某种Login()方法或某些东西,这会发送"好吧,如果你将这个哈希值传递给将来的请求,你就会被记录." 但并非所有REST客户端都希望接收cookie,只需要简单的GET/PUT/POST/DELETE请求即可.

如果那些是我的鞋子,我要么采用可信子系统方法(提供用户名标题以及子系统的预共享凭证),要么我需要在每次调用时进行身份验证.如果所有这些重复的请求都成为问题,那么该服务可能会获得一些高性能的身份验证缓存机制.

希望有所帮助.



1> Nicholas Pia..:

好吧,我对WCF的REST功能没有任何经验,但我确实在理解安全选择在WCF安全问题中的含义时遇到了很多困难.正如你所注意到的那样,WCF在Web上的文档确实缺乏,而且我的REST体验有限,所以我的答案很简单:

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

如果我使用SSL,我是否真的应该关注除纯文本以外的任何内容?

通过SSL的基本身份验证很好 - 毕竟,这是大量现有网站对用户进行身份验证的方式.(当您登录亚马逊购物帐户时,他们只是在您通过SSL连接键入时发送您的用户名和密码.)我理解文章中关于安全和字典攻击的内容,但是等等等等,请保持简单并先获得一些工作.UPS的普通旧XML API会在每次调用时询问用户名和密码,FedEx的POX API也是如此,PayPal的SOAP API和Cyber​​Source的SOAP API也是如此 - 这似乎足以满足现实世界的使用需求.

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

这是我可以更自信地回答的问题.通常,我们尝试将面向公众的WCF服务设计为无状态.这样,我们的WCF服务很容易扩展; 只是在问题上抛出更多的硬件和更多的服务器和负载均衡器,我们不必担心粘性会话或在某处维护会话状态.所以这意味着如果我们想"让用户登录",那么服务器上就不会发生这种情况.

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

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

简而言之,您将不得不通过每个请求发送一些内容来识别用户,无论是用户名和密码,只是用户名,还是存储在cookie中的一些散列值.如果是最后一个选项,我猜你必须在服务上有某种Login()方法或某些东西,这会发送"好吧,如果你将这个哈希值传递给将来的请求,你就会被记录." 但并非所有REST客户端都希望接收cookie,只需要简单的GET/PUT/POST/DELETE请求即可.

如果那些是我的鞋子,我要么采用可信子系统方法(提供用户名标题以及子系统的预共享凭证),要么我需要在每次调用时进行身份验证.如果所有这些重复的请求都成为问题,那么该服务可能会获得一些高性能的身份验证缓存机制.

希望有所帮助.



2> Tawani..:

使用基本认证:

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 factory =
             new WebChannelFactory(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);

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有