未使用認證交涉的 Windows 用戶端訊息安全性
下列案例顯示由 Kerberos 通訊協定保護的 Windows Communication Foundation (WCF) 用戶端與服務。
服務和用戶端都是在相同的網域或受信任網域中。
注意
這個案例和 Windows 用戶端的訊息安全性之間的差異是,這個案例不會在傳送應用程式訊息之前與服務交涉服務認證。 此外,因為這必須使用 Kerberos 通訊協定,所以此案例還需要 Windows 網域環境。
特性 | 描述 |
---|---|
安全性模式 | 訊息 |
互通性 | 具備此特性,有 WS-Security 搭配 Kerberos 權杖設定檔相容的用戶端 |
驗證 (伺服器) | 交互驗證伺服器和用戶端 |
驗證 (用戶端) | 交互驗證伺服器和用戶端 |
完整性 | Yes |
保密 | Yes |
傳輸 | HTTP |
繫結 | WSHttpBinding |
服務
下列程式碼和組態要獨立執行。 執行下列其中一項動作:
使用不含組態的程式碼建立獨立服務。
使用提供的組態建立服務,但不要定義任何端點。
代碼
下列程式碼會建立使用訊息安全性的服務端點。 程式碼會停用服務認證交涉以及安全性內容權杖 (SCT) 的建立。
注意
若要在沒有交涉的情況下使用 Windows 認證類型,服務的使用者帳戶必須可以存取已在 Active Directory 網域中註冊的服務主要名稱 (SPN)。 您可以使用兩種方式執行此動作:
使用
NetworkService
或LocalSystem
帳戶來執行服務。 因為這些帳戶可以存取電腦加入 Active Directory 網域時所建立的電腦 SPN,WCF 會自動在服務中繼資料 (Web 服務描述語言或 WSDL) 的服務端點內產生適當的 SPN 項目。使用任意的 Active Directory 網域帳戶來執行服務。 在這種情況下,您必須建立該網域帳戶的 SPN。 使用 Setspn.exe 公用程式工具來建立,是其中一種方法。 一旦建立了服務帳戶的 SPN,請設定 WCF 以透過它的中繼資料 (WSDL) 將該 SPN 發行至服務的用戶端。 不論是透過應用程式組態檔或程式碼,都可以設定公開端點的端點身分識別來完成此作業。 下列範例會以程式設計方式發行身分識別。
如需 SPN、Kerberos 通訊協定與 Active Directory 的詳細資訊,請參閱 Windows 的 Kerberos 技術資訊補充。 如需端點身分識別的詳細資訊,請參閱 SecurityBindingElement 驗證模式。
// Create the service host.
ServiceHost myServiceHost = new ServiceHost(typeof(Calculator));
// Create the binding.
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType =
MessageCredentialType.Windows;
// Disable credential negotiation and establishment of the
// security context.
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;
// Create a URI for the endpoint address.
Uri httpUri = new Uri("http://localhost/Calculator");
// Create the EndpointAddress with the SPN for the Identity.
EndpointAddress ea = new EndpointAddress(httpUri,
EndpointIdentity.CreateSpnIdentity("service_spn_name"));
// Get the contract from the ICalculator interface (not shown here).
// See the sample applications for an example of the ICalculator.
ContractDescription contract = ContractDescription.GetContract(
typeof(ICalculator));
// Create a new ServiceEndpoint.
ServiceEndpoint se = new ServiceEndpoint(contract, binding, ea);
// Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se);
// Open the service.
myServiceHost.Open();
Console.WriteLine("Listening...");
Console.ReadLine();
// Close the service.
myServiceHost.Close();
' Create the service host.
Dim myServiceHost As New ServiceHost(GetType(ServiceModel.Calculator))
' Create the binding.
Dim binding As New WSHttpBinding()
binding.Security.Mode = SecurityMode.Message
binding.Security.Message.ClientCredentialType = _
MessageCredentialType.Windows
' Disable credential negotiation and establishment of the
' security context.
binding.Security.Message.NegotiateServiceCredential = False
binding.Security.Message.EstablishSecurityContext = False
' Create a URI for the endpoint address.
Dim httpUri As New Uri("http://localhost/Calculator")
' Create the EndpointAddress with the SPN for the Identity.
Dim ea As New EndpointAddress(httpUri, _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))
' Get the contract from the ICalculator interface (not shown here).
' See the sample applications for an example of the ICalculator.
Dim contract As ContractDescription = ContractDescription.GetContract(GetType(ICalculator))
' Create a new ServiceEndpoint.
Dim se As New ServiceEndpoint(contract, binding, ea)
' Add the service endpoint to the service.
myServiceHost.Description.Endpoints.Add(se)
' Open the service.
myServiceHost.Open()
Console.WriteLine("Listening...")
Console.ReadLine()
' Close the service.
myServiceHost.Close()
組態
可以使用以下組態來取代程式碼。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors />
<services>
<service behaviorConfiguration="" name="ServiceModel.Calculator">
<endpoint address="http://localhost/Calculator"
binding="wsHttpBinding"
bindingConfiguration="KerberosBinding"
name="WSHttpBinding_ICalculator"
contract="ServiceModel.ICalculator"
listenUri="net.tcp://localhost/metadata" >
<identity>
<servicePrincipalName value="service_spn_name" />
</identity>
</endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="KerberosBinding">
<security>
<message negotiateServiceCredential="false"
establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client />
</system.serviceModel>
</configuration>
用戶端
下列程式碼和組態要獨立執行。 執行下列其中一項動作:
使用此程式碼 (和用戶端程式碼) 建立獨立用戶端。
建立未定義任何端點位址的用戶端, 然後改用可接受組態名稱當做引數的用戶端建構函式。 例如:
CalculatorClient cc = new CalculatorClient("EndpointConfigurationName");
Dim cc As New CalculatorClient("EndpointConfigurationName")
代碼
下列程式碼會設定用戶端。 安全性模式設定為 Message,而用戶端認證類型設定為 Windows。 請注意,NegotiateServiceCredential 和 EstablishSecurityContext 屬性會設定為 false
。
注意
若要在沒有交涉的情況下使用 Windows 認證類型,就必須先使用服務的帳戶 SPN 設定用戶端,再開始與服務進行通訊。 用戶端會使用 SPN 取得 Kerberos 權杖,以驗證並保護與服務進行的通訊。 下列範例示範如何使用服務的 SPN 來設定用戶端。 當您正在使用 ServiceModel 中繼資料公用程式工具 (Svcutil.exe) 產生用戶端時,如果服務的中繼資料包含服務的 SPN,這項資訊將會自動從服務的中繼資料 (WSDL) 傳播至用戶端。 如需如何設定服務以在服務中繼資料內包含其 SPN 的詳細資訊,請參閱本主題稍後的<服務>一節。
如需 SPN、Kerberos 與 Active Directory 的詳細資訊,請參閱 Windows 的 Kerberos 技術資訊補充。 如需端點身分識別的詳細資訊,請參閱 SecurityBindingElement 驗證模式主題。
// Create the binding.
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
MessageCredentialType.Windows;
// Disable credential negotiation and the establishment of
// a security context.
myBinding.Security.Message.NegotiateServiceCredential = false;
myBinding.Security.Message.EstablishSecurityContext = false;
// Create the endpoint address and set the SPN identity.
// The SPN must match the identity of the service's SPN.
// If using SvcUtil to generate a configuration file, the SPN
// will be published as the <servicePrincipalName> element under the
// <identity> element.
EndpointAddress ea = new EndpointAddress(
new Uri("http://machineName/Calculator"),
EndpointIdentity.CreateSpnIdentity("service_spn_name"));
// Create the client.
CalculatorClient cc =
new CalculatorClient(myBinding, ea);
// Begin using the client.
try
{
cc.Open();
Console.WriteLine(cc.Add(200, 1111));
Console.ReadLine();
// Close the client.
cc.Close();
}
' Create the binding.
Dim myBinding As New WSHttpBinding()
myBinding.Security.Mode = SecurityMode.Message
myBinding.Security.Message.ClientCredentialType = _
MessageCredentialType.Windows
' Disable credential negotiation and the establishment of
' a security context.
myBinding.Security.Message.NegotiateServiceCredential = False
myBinding.Security.Message.EstablishSecurityContext = False
' Create the endpoint address and set the SPN identity.
' The SPN must match the identity of the service's SPN.
' If using SvcUtil to generate a configuration file, the SPN
' will be published as the <servicePrincipalName> element under the
' <identity> element.
Dim ea As New EndpointAddress(New Uri("http://machineName/calculator"), _
EndpointIdentity.CreateSpnIdentity("service_spn_name"))
' Create the client.
Dim cc As New CalculatorClient(myBinding, ea)
' Begin using the client.
Try
cc.Open()
Console.WriteLine(cc.Add(100, 11))
Console.ReadLine()
' Close the client.
cc.Close()
Catch tex As TimeoutException
Console.WriteLine(tex.Message)
cc.Abort()
Catch cex As CommunicationException
Console.WriteLine(cex.Message)
cc.Abort()
Finally
Console.WriteLine("Closed the client")
Console.ReadLine()
End Try
組態
下列程式碼會設定用戶端。 請注意,<servicePrincipalName> 元素必須設定為符合服務帳戶在 Active Directory 網域中註冊的服務 SPN。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator" >
<security mode="Message">
<message clientCredentialType="Windows"
negotiateServiceCredential="false"
establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/Calculator"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator"
contract="ICalculator"
name="WSHttpBinding_ICalculator">
<identity>
<servicePrincipalName value="service_spn_name" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>