一、netTCPBinding.1
1、安全模式 – None.2
2、安全模式 - Transport.4
2.1.客戶端驗證:Windows.4
2.2.客戶端驗證:None.5
2.2.1.獲得和安裝證書...6
2.2.2.服務端代碼...6
2.2.3.客戶端代碼...6
2.2.4.測試...7
2.3.客戶端驗證:Certificate.8
2.3.1.獲得和安裝證書...9
2.3.2.服務端代碼...9
2.3.3.客戶端代碼...9
2.3.4.測試...10
2.3.5.證書映射到windows用戶...10
一、netTCPBinding
此綁定使用TCP傳輸協議,不具交互性,只適用於 WCF 到 WCF 的通信。
此綁定的傳輸安全性的實現:
l 安全模式Message
這種模式WCF中都一樣,都是使用WS-*通過對SOAP消息本身進行加密、簽名等 等的處理來保證安全性。Message模式不依賴於傳輸協議。服務端需要指定服務 端證書,用來加密服務端和客戶端相互傳送的消息。
l Transport – 客戶端windows驗證
使用windows security保證消息的安全,使用windows credential進行身份 驗證。
這種方式不需要服務端證書。
至於windows security的實現安全的原理我還不明白,這部分尚待了解。
l Transport – 客戶端其他驗證方式
使用TLS over TCP實現傳輸安全性,需要服務端證書。
一般大家對SSL比較熟悉,對TLS可能要陌生些,其實可以說TLS協議可以看作 跟SSL協議後續版本。1994年,netscape為了在internet上進行安全的數據傳輸 ,開發了的SSL協議,後來標准化組織把SSL標准化了,稍作修改改名叫TLS,在 一般的使用意義上,這兩個協議差別不大,就是在保證消息完整性的散列算法上 使用了不同的算法。
TLS over TCP 直接建立在TCP協議上,通過傳輸層TCP協議實現安全性。
netTCPBinding綁定是直接使用TCP協議,不走HTTP,所以不能使用IIS宿主。 這部分的測試實例采用自宿主的服務端console應用,基於代碼的方式。
測試環境
l 服務端:
服務器名:win2008
操作系統:Windows server 2008
開發環境:visual studio 2008
運行環境:.net framework 3.5
Web服務器: IIS 7.0
浏覽器:IE 7.0
l 客戶端:
服務端機器同時充當測試客戶端機器,同時准備了一台win2003的機器做測試 客戶端:
計算機名:win2003base2
操作系統:Windows server 2003
運行環境:.net framework 3.5
浏覽器:IE 7.0
共用測試WCF服務類
所有測試都是用同樣的服務端contract和實現這個contract的service:
[ServiceContract(Namespace = "http://chnking.com")]
public interface IGetIdentity
{
[OperationContract]
string Get(string ClientIdentity);
}
public class GetIdentity : IGetIdentity
{
public string Get(string ClientIdentity)
{
return ("服務端Identity 是'" + ServiceSecurityContext.Current.PrimaryIdentity.Name +
"'\n\r客戶端Identity是 '" + ClientIdentity + "'");
}
}
代碼很簡單,一個contract提供了一個Get方法,接收一個string參數,返回 一個string參數。在後面的測試中,客戶端把客戶端安全上下文的Identity發送 到服務端,服務端返回服務端安全上下文的Identity給客戶端。
1、安全模式 – None
這部分的測試代碼:NetTcpBinding_None.rar
netTCPBinding綁定默認的安全模式是Transport,提供傳輸層的安全性,但 是也提供None安全模式的選擇,None安全模式不提供任何安全性和身份驗證。
這種方式的安全性:
完整性 不提供 保密性 不提供 服務端身份身份驗證 不提供 客戶端身份驗證 無,並忽略客戶端驗證的其他方式設置,固定為None
本例采用全代碼方式,不使用配置文件。
服務端代碼:
internal static void Main()
{
NetTcpBinding myBinding = new NetTcpBinding();
myBinding.Security.Mode = SecurityMode.None;
myBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
Uri baseAddress = new Uri ("net.tcp://localhost:8056/WCFService/");
myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);
ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint
(typeof(IGetIdentity), myBinding, "GetIdentity");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior ();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri ("http://localhost:8057/mex");
myServiceHost.Description.Behaviors.Add(behavior);
myServiceHost.Open();
Console.WriteLine("Service started!");
Console.ReadLine();
myServiceHost.Close();
}
客戶端代碼:
static void Main(string[] args)
{
NetTcpBinding myBinding = new NetTcpBinding();
myBinding.Security.Mode = SecurityMode.None;
myBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
EndpointAddress ea = new EndpointAddress ("net.tcp://localhost:8056/WCFService/GetIdentity");
GetIdentityClient gc = new GetIdentityClient(myBinding, ea);
//為使用TcpTrace跟蹤消息設置的TcpTrace監聽端口
ClientViaBehavior myClientViaBehavior = new ClientViaBehavior
(new Uri ("net.tcp://localhost:8055/WCFService/GetIdentity"));
gc.Endpoint.Behaviors.Add(myClientViaBehavior);
//執行代理類Get方法
string result = gc.Get(WindowsIdentity.GetCurrent().Name);
Console.WriteLine(result);
Console.ReadLine();
}
客戶端設置了ClientVia的Vehavior,設置8055為監聽端口,8056為實際端口 ,同時運行TcpTrace來跟蹤通訊數據,客戶端運行結果:
TCPTrace工具抓客戶端和服務端的通訊數據:
從TcpTrace的截獲的通訊數據可以看出:
l netTCPBinding綁定采用binary編碼。
l netTCPBinding的None安全模式不對消息加密,從截獲的數據可以看到返 回的消息中文本部分是明文。
2、安全模式 - Transport
2.1.客戶端驗證:Windows
這部分的測試代碼: NetTcpBinding_Transport_Windows.rar
netTCPBinding綁定的Transport安全模式,提供傳輸層的安全性,客戶端 Windows驗證,此時將采用windows security在傳輸層來保證消息的安全性。
這種方式的安全性:
完整性 由windows security提供 保密性 由windows security提供 服務端身份身份驗證 Windows集成驗證 客戶端身份驗證 客戶端Windows credential通過Windows繼承驗證客戶端身份
本例采用全代碼方式,不使用配置文件。代碼部分是在前面None安全模式代 碼基礎上在服務端和客戶端的代碼中將安全模式改為Transport,客戶端驗證方 式改為Windows即可。
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
客戶端運行結果:
TCPTrace工具抓客戶端和服務端的通訊數據:
從TcpTrace的截獲的通訊數據可以看出:
l netTCPBinding綁定式采用binary編碼。
l netTCPBinding的Transport安全模式對消息加密,從截獲的數據可以看到 返回的消息中也看不到明文。
2.2.客戶端驗證:None
這部分的測試代碼: NetTcpBinding_Transport_None.rar
netTCPBinding綁定的Transport安全模式,客戶端None驗證,此時將采用TLS 協議在傳輸層來保證消息的安全性。
這種方式的安全性:
完整性 由TLS提供 保密性 由TLS提供 服務端身份身份驗證 服務端證書提供 客戶端身份驗證 沒有
2.2.1.獲得和安裝證書
TLS跟SSL一樣,需要設置服務端證書。
這裡用Makecert.exe工具生成證書,使用下面的命令:
makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe - r
這是服務端證書,win2008是服務端的機器名。
如果做過前面BasicHttpBinding的測試,這個服務端證書就應該已經有了。
2.2.2.服務端代碼
internal static ServiceHost myServiceHost = null;
internal static void Main()
{
NetTcpBinding myBinding = new NetTcpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
Uri baseAddress = new Uri ("net.tcp://win2008:8056/WCFService/");
myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);
ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint
(typeof(IGetIdentity), myBinding, "GetIdentity");
//設置服務端證書
myServiceHost.Credentials.ServiceCertificate.SetCertificate ("CN=win2008");
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior ();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri ("http://win2008:8057/mex");
myServiceHost.Description.Behaviors.Add(behavior);
myServiceHost.Open();
Console.WriteLine("Service started!");
Console.ReadLine();
myServiceHost.Close();
}
2.2.3.客戶端代碼
static void Main(string[] args)
{
NetTcpBinding myBinding = new NetTcpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
EndpointAddress ea = new EndpointAddress ("net.tcp://win2008:8056/WCFService/GetIdentity");
GetIdentityClient gc = new GetIdentityClient(myBinding, ea);
//設置不驗證服務端證書有效性
gc.ClientCredentials.ServiceCertificate.Authentication.CertificateVali dationMode =
System.ServiceModel.Security.X509CertificateValidationMode.None;
//為使用TcpTrace跟蹤消息設置的TcpTrace監聽端口
ClientViaBehavior myClientViaBehavior = new ClientViaBehavior
(new Uri ("net.tcp://win2008:8055/WCFService/GetIdentity"));
gc.Endpoint.Behaviors.Add(myClientViaBehavior);
//執行代理類Get方法
string result = gc.Get(WindowsIdentity.GetCurrent().Name);
Console.WriteLine(result);
Console.ReadLine();
}
2.2.4.測試
客戶端運行結果:
TCPTrace工具抓客戶端和服務端的通訊數據:
從TcpTrace的截獲的通訊數據可以看出:
l netTCPBinding綁定式采用binary編碼。
l netTCPBinding的Transport安全模式對消息加密,從截獲的數據可以看到 返回的消息中也看不到明文。
2.3.客戶端驗證:Certificate
這部分的測試代碼: NetTcpBinding_Transport_Certificate.rar
netTCPBinding綁定的Transport安全模式,客戶端Certificate驗證,此時將 采用TLS協議在傳輸層來保證消息的安全性。
這種方式的安全性:
完整性 由TLS提供 保密性 由TLS提供 服務端身份身份驗證 服務端證書提供 客戶端身份驗證 客戶端證書提供
2.3.1.獲得和安裝證書
TLS跟SSL一樣,需要設置服務端證書。
同時客戶端驗證設置為Certificate,就需要提供客戶端證書以驗證客戶端身 份。
所有這裡需要在服務端和客戶端分別安裝證書。
這裡用Makecert.exe工具生成證書,使用下面的命令:
makecert -sr localmachine -ss My -n CN=win2008 -sky exchange -pe - r
這是服務端證書,win2008是服務端的機器名。
如果做過前面BasicHttpBinding的測試,這個服務端證書就應該已經有了。
makecert -sr currentuser -ss My -n CN=TestClient -sky exchange -pe -r
這是客戶端證書。
2.3.2.服務端代碼
internal static ServiceHost myServiceHost = null;
internal static void Main()
{
NetTcpBinding myBinding = new NetTcpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
Uri baseAddress = new Uri ("net.tcp://win2008:8056/WCFService/");
myServiceHost = new ServiceHost(typeof(GetIdentity), baseAddress);
ServiceEndpoint myServiceEndpoint = myServiceHost.AddServiceEndpoint
(typeof(IGetIdentity), myBinding, "GetIdentity");
//設置服務端證書
myServiceHost.Credentials.ServiceCertificate.SetCertificate ("CN=win2008");
//設置不驗證客戶端證書的有效性
myServiceHost.Credentials.ClientCertificate.Authentication.Certificate ValidationMode =
System.ServiceModel.Security.X509CertificateValidationMode.None;
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior ();
behavior.HttpGetEnabled = true;
behavior.HttpGetUrl = new Uri ("http://win2008:8057/mex");
myServiceHost.Description.Behaviors.Add(behavior);
myServiceHost.Open();
Console.WriteLine("Service started!");
Console.ReadLine();
myServiceHost.Close();
}
2.3.3.客戶端代碼
static void Main(string[] args)
{
NetTcpBinding myBinding = new NetTcpBinding();
myBinding.Security.Mode = SecurityMode.Transport;
myBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
EndpointAddress ea = new EndpointAddress ("net.tcp://win2008:8056/WCFService/GetIdentity");
GetIdentityClient gc = new GetIdentityClient(myBinding, ea);
//設置客戶端證書
gc.ClientCredentials.ClientCertificate.SetCertificate ("CN=TestClient",
StoreLocation.CurrentUser, StoreName.My);
//設置不驗證服務端證書有效性
gc.ClientCredentials.ServiceCertificate.Authentication.CertificateVali dationMode =
System.ServiceModel.Security.X509CertificateValidationMode.None;
//為使用TcpTrace跟蹤消息設置的TcpTrace監聽端口
ClientViaBehavior myClientViaBehavior = new ClientViaBehavior
(new Uri ("net.tcp://win2008:8055/WCFService/GetIdentity"));
gc.Endpoint.Behaviors.Add(myClientViaBehavior);
//執行代理類Get方法
string result = gc.Get(WindowsIdentity.GetCurrent().Name);
Console.WriteLine(result);
Console.ReadLine();
}
2.3.4.測試
由於客戶端是Certificate身份驗證,到了服務端 ServiceSecurityContext.Current.WindowsIdentity.Name獲得的是證書的 subject name和證書指紋。
2.3.5.證書映射到windows用戶
有時需要把客戶端證書映射為服務端的windows用戶,這樣可以使用windows 權限控制客戶端在服務端的權限。
在本例的情況,可以設置客戶端證書跟服務端windows用戶的映射,首先在服 務端的代碼或配置文件中設置允許客戶端證書到服務端windows用戶的映射。
代碼中將客戶端驗證MapClientCertificateToWindowsAccount設為True:
myServiceHost.Credentials.ClientCertificate.Authentication.Ma pClientCertificateToWindowsAccount = true;
配置文件中將服務端Behavior的客戶端證書驗證 MapClientCertificateToWindowsAccount設為True:
<serviceBehaviors>
<behavior>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None" mapClientCertificateToWindowsAccount="True" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
然後根據不同的服務端不同的宿主分別設置映射,分兩種情況:
l 宿主為IIS 7.0
在IIS中設置客戶端證書到windows用戶的映射,可以一對一的映射,也可以 多對一的映射,具體參考文章:IIS 7 Walkthrough: One to One Client Certificate Mapping Configuration: http://blogs.iis.net/rlucero/archive/2008/05/23/iis-7-walkthrough-one -to-one-client-certificate-mapping-configuration.aspx
l 宿主為console應用或服務
這是直接在操作系統上把客戶端的證書與windows用戶作映射,這必須是要在 安裝了Active Directory的服務器上做。
具體步驟參考文章:Map certificates to user accounts:
http://technet2.microsoft.com/WindowsServer/f/?en/library/0539dcf5 -82c5-48e6-be8a-57bca16c7e171033.mspx