WCF简单教程(8) 安全 - Windows认证
第八篇:WCF安全
WCF提供了非常豐富的加密機制與審核機制,以保證對外提供的服務安全可靠。本文是簡單教程,所以只挑其中的一小部分來聊聊。
先來看看最簡單的Windows認證。
所謂Windows認證,是指客戶端訪問時,要提供服務端認可的Windows用戶身份。
1、服務端
安全配置主要體現(xiàn)在App.config中:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<system.serviceModel>
<services>
<servicename="Server.DataProvider">
? ? ? ?<!-- 本例中使用netTcpBinding,注意指定了一個名為tcpBinding的設置,見下文 -->
<endpointaddress=""binding="netTcpBinding"contract="Server.IData"bindingConfiguration="tcpBinding"/>
<host>
<baseAddresses>
<addbaseAddress="net.tcp://localhost:8081/wcf"/>
</baseAddresses>
</host>
</service>
</services>
<!--客戶端的身份認證是設置在bindings節(jié)中的-->
<bindings>
? ? ?<!--注意此節(jié)要與前面的binding匹配,表示為netTcpBinding方式的綁定進行配置-->
<netTcpBinding>
? ? ? ?<!--定義一個名為tcpBinding的設置,就是前面endpoint中用到的-->
<bindingname="tcpBinding">
? ? ? ? ?<!--使用Message方式的加密,至于它與Transport方式的區(qū)別,可先忽略,后面再講-->
<securitymode="Message">
? ? ? ? ? ?<!--指定客戶端認證使用Windows方式-->
<messageclientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
契約實現(xiàn)類我們修改一下,方便看到調(diào)用者的身份:
using System;
using System.ServiceModel;
namespace Server
{
? ?[ServiceBehavior]
publicclass DataProvider : IData
? ?{
publicstring SayHello()
? ? ? ?{
? ? ? ? ? ?//WindowsIdentity即代表訪問者的身份標識
returnstring.Format("Hello {0}", OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name);
? ? ? ?}
? ?}
}
2、客戶端
客戶端要對應調(diào)整App.config:
<?xmlversion="1.0"encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client>
? ? ?<!--定義endpoint時指定使用特定的配置,另外這個IP是一會兒運行服務端的機器的IP-->
<endpointbinding="netTcpBinding"contract="Server.IData"address="net.tcp://192.168.90.90:8081/wcf"name="DataProvider"bindingConfiguration="tcp"/>
</client>
? ?<!--客戶端與服務端的bindings節(jié)設置一致-->
<bindings>
<netTcpBinding>
<bindingname="tcp">
<securitymode="Message">
<messageclientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
然后是代碼,要指定訪問時客戶端使用的用戶名密碼:
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace Client
{
class Program
? ?{
staticvoid Main(string[] args)
? ? ? ?{
? ? ? ? ? ?//創(chuàng)建一個ChannelFactory,指定使用名為DataProvider的配置
? ? ? ? ? ?var factory = new ChannelFactory<Server.IData>("DataProvider");
? ? ? ? ? ?//指定用戶名、密碼,這個Test是服務端Windows上的一個普通帳戶,如果加入了域,還要指定ClientCredential.Domain
? ? ? ? ? ?factory.Credentials.Windows.ClientCredential.UserName= "Test";
? ? ? ? ? ?factory.Credentials.Windows.ClientCredential.Password = "test";
? ? ? ? ? ?//創(chuàng)建Channel,并調(diào)用SayHello方法
? ? ? ? ? ?var proxy = factory.CreateChannel();
? ? ? ? ? ?Console.WriteLine(proxy.SayHello());
? ? ? ? ? ?((IChannel)proxy).Close();
? ? ? ?}
? ?}
}
其中的指定的用戶名與密碼是服務端存在的一個Windows用戶。
OK,在兩臺機器上分別運行服務端和客戶端,能夠正常完成調(diào)用,輸出“Hello Test-PC\Test”,這個Test-PC\Test就是我們調(diào)用時傳遞的用戶身份,注意是“機器名\用戶名”的形式,如果是AD環(huán)境,那么就是“域\用戶名”的形式。
如果給定一個錯誤的用戶名密碼,則調(diào)用時會收到Exception:
未處理的異常: ?System.ServiceModel.Security.SecurityNegotiationException: 調(diào)用方未由服務進行身份驗證。 ---> System.ServiceModel.FaultException: 無法滿足對安全令牌的請求,因為身份驗證失敗。
? 在 System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
? 在 System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
是一個身份驗證失敗的異常。
用Windows帳戶來做驗證,其實是個挺麻煩的事情,只有較少的系統(tǒng)是這么做的,我們還是希望能用更通用的用戶名密碼來進行身份驗證,下一篇我們就來看看如何做。
本文出自 “兔子窩” 博客,請務必保留此出處http://boytnt.blog.51cto.com/966121/815117
轉(zhuǎn)載于:https://blog.51cto.com/rmlifejun/1264407
總結(jié)
以上是生活随笔為你收集整理的WCF简单教程(8) 安全 - Windows认证的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的nginx iis 负载均衡学习(环
- 下一篇: tomcat 系统服务 outofmem