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