设为首页 收藏本站
查看: 824|回复: 0

[经验分享] WCF简单教程(8) 安全

[复制链接]

尚未签到

发表于 2018-6-13 08:01:04 | 显示全部楼层 |阅读模式
  第八篇:WCF安全
  WCF提供了非常丰富的加密机制与审核机制,以保证对外提供的服务安全可靠。本文是简单教程,所以只挑其中的一小部分来聊聊。
  先来看看最简单的Windows认证。
  所谓Windows认证,是指客户端访问时,要提供服务端认可的Windows用户身份。
  1、服务端
  安全配置主要体现在App.config中:


  • <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?>
  • <configuration>
  •   <system.serviceModel>
  •     <services>
  •       <service name=&quot;Server.DataProvider&quot;>
  •         <!-- 本例中使用netTcpBinding,注意指定了一个名为tcpBinding的设置,见下文 -->
  •         <endpoint address=&quot;&quot; binding=&quot;netTcpBinding&quot; contract=&quot;Server.IData&quot; bindingConfiguration=&quot;tcpBinding&quot; />
  •         <host>
  •           <baseAddresses>
  •             <add baseAddress=&quot;net.tcp://localhost:8081/wcf&quot; />
  •           </baseAddresses>
  •         </host>
  •       </service>
  •     </services>

  •     <!--客户端的身份认证是设置在bindings节中的-->
  •     <bindings>
  •       <!--注意此节要与前面的binding匹配,表示为netTcpBinding方式的绑定进行配置-->
  •       <netTcpBinding>
  •         <!--定义一个名为tcpBinding的设置,就是前面endpoint中用到的-->
  •         <binding name=&quot;tcpBinding&quot;>
  •           <!--使用Message方式的加密,至于它与Transport方式的区别,可先忽略,后面再讲-->
  •           <security mode=&quot;Message&quot;>
  •             <!--指定客户端认证使用Windows方式-->
  •             <message clientCredentialType=&quot;Windows&quot; />
  •           </security>
  •         </binding>
  •       </netTcpBinding>
  •     </bindings>
  •   </system.serviceModel>
  • </configuration>

  契约实现类我们修改一下,方便看到调用者的身份:


  • using System;
  • using System.ServiceModel;

  • namespace Server
  • {
  •     [ServiceBehavior]
  •     public class DataProvider : IData
  •     {
  •         public string SayHello()
  •         {
  •             //WindowsIdentity即代表访问者的身份标识
  •             return string.Format(&quot;Hello {0}&quot;, OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name);
  •         }
  •     }
  • }

  
2、客户端
  客户端要对应调整App.config:


  • <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?>
  • <configuration>
  •   <system.serviceModel>
  •     <client>
  •       <!--定义endpoint时指定使用特定的配置,另外这个IP是一会儿运行服务端的机器的IP-->
  •       <endpoint binding=&quot;netTcpBinding&quot; contract=&quot;Server.IData&quot; address=&quot;net.tcp://192.168.90.90:8081/wcf&quot; name=&quot;DataProvider&quot; bindingConfiguration=&quot;tcp&quot; />
  •     </client>
  •     <!--客户端与服务端的bindings节设置一致-->
  •     <bindings>
  •       <netTcpBinding>
  •         <binding name=&quot;tcp&quot;>
  •           <security mode=&quot;Message&quot;>
  •             <message clientCredentialType=&quot;Windows&quot; />
  •           </security>
  •         </binding>
  •       </netTcpBinding>
  •     </bindings>
  •   </system.serviceModel>
  • </configuration>

  
然后是代码,要指定访问时客户端使用的用户名密码:



  • using System;
  • using System.ServiceModel;
  • using System.ServiceModel.Channels;

  • namespace Client
  • {
  •     class Program
  •     {
  •         static void Main(string[] args)
  •         {
  •             //创建一个ChannelFactory,指定使用名为DataProvider的配置
  •             var factory = new ChannelFactory<Server.IData>(&quot;DataProvider&quot;);

  •             //指定用户名、密码,这个Test是服务端Windows上的一个普通帐户,如果加入了域,还要指定ClientCredential.Domain
  •             factory.Credentials.Windows.ClientCredential.UserName= &quot;Test&quot;;
  •             factory.Credentials.Windows.ClientCredential.Password = &quot;test&quot;;

  •             //创建Channel,并调用SayHello方法
  •             var proxy = factory.CreateChannel();
  •             Console.WriteLine(proxy.SayHello());
  •             ((IChannel)proxy).Close();
  •         }
  •     }
  • }

  其中的指定的用户名与密码是服务端存在的一个Windows用户。
  
OK,在两台机器上分别运行服务端和客户端,能够正常完成调用,输出“Hello Test-PC\Test”,这个Test-PC\Test就是我们调用时传递的用户身份,注意是“机器名\用户名”的形式,如果是AD环境,那么就是“域\用户名”的形式。

  如果给定一个错误的用户名密码,则调用时会收到Exception:


  • 未处理的异常:  System.ServiceModel.Security.SecurityNegotiationException: 调用方未由服务进行身份验证。 ---> System.ServiceModel.FaultException: 无法满足对安全令牌的请求,因为身份验证失败。
  •    在 System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
  •    在 System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)

  是一个身份验证失败的异常。
  
用Windows帐户来做验证,其实是个挺麻烦的事情,只有较少的系统是这么做的,我们还是希望能用更通用的用户名密码来进行身份验证,下一篇我们就来看看如何做。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-522978-1-1.html 上篇帖子: zabbix监控windows日志脚本 下篇帖子: 解决Windows Server 2008 System进程占用80端口
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表