HOW TO:使用 Windows 認證來確保服務安全
這個主題會示範如何針對位於 Windows 網域中,而且是由相同網域中的用戶端所呼叫的 Windows Communication Foundation (WCF) 服務,啟用其上面的傳輸安全性。如需詳細資訊此案例的詳細資訊,請參閱Windows 驗證的傳輸安全性。如需範例應用程式,請參閱 WSHttpBinding 範例。
這個主題假設您擁有現有的合約介面、已定義了實作 (Implementation),以及一些附加內容。您也可以修改現有的服務和用戶端。
您可以完全使用程式碼,透過 Windows 認證來確保服務安全。或者,您也可以使用組態檔來省略部分程式碼。這個主題會說明這兩種方式。請務必只使用其中一種方式,不要兩種都使用。
前三個程序會說明如何使用程式碼來保護服務安全。第四和第五個程序會說明如何使用組態檔來執行這項作業。
使用程式碼
服務和用戶端的完整程式碼已提供於本主題結尾的「範例」一節。
第一個程序會逐步解說如何使用程式碼建立和設定 WSHttpBinding 類別。繫結會使用 HTTP 傳輸。用戶端上會使用相同的繫結。
建立會使用 Windows 認證和訊息安全性的 WSHttpBinding
這個程序的程式碼會插入至「範例」一節服務程式碼中
Test
類別的Run
方法開頭。建立 WSHttpBinding 類別的執行個體。
將 WsHttpSecurity 類別的 Mode 屬性設定為 Message。
將 MessageSecurityOverHttp 類別的 ClientCredentialType 屬性設定為 Windows。
這項程序的程式碼如下所示:
Dim myBinding As New WSHttpBinding() myBinding.Security.Mode = SecurityMode.Message myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
// First procedure: // create a WSHttpBinding that uses Windows credentials and message security WSHttpBinding myBinding = new WSHttpBinding(); myBinding.Security.Mode = SecurityMode.Message; myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
在服務中使用繫結
這是第二個程序,說明如何在自我裝載的服務中使用繫結。如需詳細資訊裝載服務的詳細資訊,請參閱裝載服務。
在服務中使用繫結
將這個程序的程式碼插入到前一個程序的程式碼後面。
建立名稱為
contractType
的 Type 變數,並將其類型指派為介面 (ICalculator
)。使用 Visual Basic 時,請使用 GetType 運算子;使用 C# 時,請使用 typeof 關鍵字。建立第二個名稱為
serviceType
的 Type 變數,並將其類型指派為實作的合約 (Calculator
)。使用服務的基底位址,建立名稱為
baseAddress
之 Uri 類別的執行個體。基底位址必須具有符合傳輸的配置。在這個情況下,傳輸配置為 HTTP,而位址中則包含特殊統一資源識別項 (URI) "localhost"、連接埠號碼 (8036) 和基底端點位址 (serviceModelSamples/):https://localhost:8036/serviceModelSamples/。使用
serviceType
和baseAddress
變數,建立 ServiceHost 類別的執行個體。使用
contractType
、繫結和端點名稱 (secureCalculator),將端點新增至服務。初始化服務的呼叫時,用戶端必須串連基底位址和端點名稱。呼叫 Open 方法啟動服務。這項程序的程式碼如下所示:
' Create the Type instances for later use and the URI for ' the base address. Dim contractType As Type = GetType(ICalculator) Dim serviceType As Type = GetType(Calculator) Dim baseAddress As New Uri("https://localhost:8036/serviceModelSamples/") ' Create the ServiceHost and add an endpoint, then start ' the service. Dim myServiceHost As New ServiceHost(serviceType, baseAddress) myServiceHost.AddServiceEndpoint(contractType, myBinding, "secureCalculator") myServiceHost.Open()
// 2nd Procedure: // Use the binding in a service // Create the Type instances for later use and the URI for // the base address. Type contractType = typeof(ICalculator); Type serviceType = typeof(Calculator); Uri baseAddress = new Uri("https://localhost:8036/SecuritySamples/"); // Create the ServiceHost and add an endpoint, then start // the service. ServiceHost myServiceHost = new ServiceHost(serviceType, baseAddress); myServiceHost.AddServiceEndpoint (contractType, myBinding, "secureCalculator"); //enable metadata ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; myServiceHost.Description.Behaviors.Add(smb); myServiceHost.Open();
在用戶端中使用繫結
這項程序會說明如何產生與服務進行通訊的 Proxy。此 Proxy 是使用 ServiceModel 中繼資料公用程式工具 (Svcutil.exe) 所產生,該工具會使用服務中繼資料建立 Proxy。
此程序還會建立可與服務進行通訊之 WSHttpBinding 類別的執行個體,然後呼叫該服務。
這個範例只會使用程式碼來建立用戶端。或者,您可以使用組態檔,該檔案會在此程序之後的章節中說明。
搭配程式碼在用戶端中使用繫結
使用 SvcUtil.exe 工具,從服務的中繼資料產生 Proxy 程式碼。如需詳細資訊,請參閱 HOW TO:建立 Windows Communication Foundation 用戶端. 產生的 Proxy 程式碼繼承自 ClientBase 類別,這樣可確保每個用戶端都有與 WCF 服務進行通訊時所需要的建構函式、方法和屬性。在這個範例中,產生的程式碼包含
CalculatorClient
類別,這個類別會實作ICalculator
介面,因此就會與服務程式碼相容。此程序的程式碼會插入至用戶端程式的
Main
方法開頭。建立 WSHttpBinding 類別的執行個體,將其安全性模式設定為 Message,並將其用戶端認證類型設定為 Windows。這個範例會將變數命名為
clientBinding
。建立名稱為
serviceAddress
之 EndpointAddress 類別的執行個體。使用與端點名稱串連的基底位址初始化執行個體。使用
serviceAddress
和clientBinding
變數,建立產生之用戶端類別的執行個體。呼叫 Open 方法,如下列程式碼所示。
呼叫服務並顯示結果。
Dim b As New WSHttpBinding(SecurityMode.Message) b.Security.Message.ClientCredentialType = MessageCredentialType.Windows Dim ea As New EndpointAddress("net.tcp://machinename:8036/endpoint") Dim cc As New CalculatorClient(b, ea) cc.Open() ' Alternatively, use a binding name from a configuration file generated by the ' SvcUtil.exe tool to create the client. Omit the binding and endpoint address ' because that information is provided by the configuration file. ' CalculatorClass cc = new CalculatorClient("ICalculator_Binding")
// 3rd Procedure: // Creating a binding and using it in a service // To run using config, comment the following lines, and uncomment out the code // following this section WSHttpBinding b = new WSHttpBinding(SecurityMode.Message); b.Security.Message.ClientCredentialType = MessageCredentialType.Windows; EndpointAddress ea = new EndpointAddress("Http://localhost:8036/SecuritySamples/secureCalculator"); CalculatorClient cc = new CalculatorClient(b, ea); cc.Open(); // Now call the service and display the results // Call the Add service operation. double value1 = 100.00D; double value2 = 15.99D; double result = cc.Add(value1, value2); Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result); // Closing the client gracefully closes the connection and cleans up resources. cc.Close();
使用組態檔
如果不使用程序程式碼建立繫結,您可以改用下面針對組態檔之繫結區段所顯示的程式碼。
注意:這個組態程式碼會同時在服務和用戶端組態檔中使用。
使用組態在 Windows 網域的服務上啟用傳輸安全性
將 <wsHttpBinding> 項目新增至組態檔的 <bindings> 項目區段中。
將 <binding> 項目新增至 <WSHttpBinding> 項目,並將 configurationName 屬性設定為適用於您應用程式的值。
新增 <security> 項目,並將 mode 屬性設定為 Message。
新增 <message> 項目,並將 clientCredentialType 屬性設定為 Windows。
在服務的組態檔中,將 <bindings> 區段取代為下列程式碼。如果您尚未建立服務組態檔,請參閱使用繫結來設定服務和用戶端。
<bindings> <wsHttpBinding> <binding name = "wsHttpBinding_Calculator"> <security mode="Message"> <message clientCredentialType="Windows"/> </security> </binding> </wsHttpBinding> </bindings>
在用戶端中使用繫結
此程序會說明如何產生兩個檔案:與服務進行通訊的 Proxy 及組態檔。此外還會說明用戶端程式的變更,也就是用戶端上使用的第三個檔案。
搭配組態在用戶端中使用繫結
使用 SvcUtil.exe 工具,從服務的中繼資料產生 Proxy 程式碼和組態檔。如需詳細資訊,請參閱 HOW TO:建立 Windows Communication Foundation 用戶端.
將已產生之組態檔的 <Bindings> 區段取代為前一個區段的組態程式碼。
程序程式碼會插入至用戶端程式的
Main
方法開頭。建立已產生之用戶端類別的執行個體,將組態檔中繫結的名稱當做輸入參數傳遞。
呼叫 Open 方法,如下列程式碼所示。
呼叫服務並顯示結果。
// 4th Procedure: // Using config instead of the binding-related code // In this case, use a binding name from a configuration file generated by the // SvcUtil.exe tool to create the client. Omit the binding and endpoint address // because that information is provided by the configuration file. CalculatorClient cc = new CalculatorClient("ICalculator_Binding"); cc.Open(); // Now call the service and display the results // Call the Add service operation. double value1 = 100.00D; double value2 = 15.99D; double result = cc.Add(value1, value2); Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result); // Closing the client gracefully closes the connection and cleans up resources. cc.Close();
範例
using System;
using System.Collections;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Security.Permissions;
[assembly: SecurityPermission(SecurityAction.RequestMinimum, Execution = true)]
namespace Microsoft.Security.Samples
{
public class Test
{
static void Main()
{
Test t = new Test();
Console.WriteLine("Starting....");
t.Run();
}
private void Run()
{
// First procedure:
// create a WSHttpBinding that uses Windows credentials and message security
WSHttpBinding myBinding = new WSHttpBinding();
myBinding.Security.Mode = SecurityMode.Message;
myBinding.Security.Message.ClientCredentialType =
MessageCredentialType.Windows;
// 2nd Procedure:
// Use the binding in a service
// Create the Type instances for later use and the URI for
// the base address.
Type contractType = typeof(ICalculator);
Type serviceType = typeof(Calculator);
Uri baseAddress = new
Uri("https://localhost:8036/SecuritySamples/");
// Create the ServiceHost and add an endpoint, then start
// the service.
ServiceHost myServiceHost =
new ServiceHost(serviceType, baseAddress);
myServiceHost.AddServiceEndpoint
(contractType, myBinding, "secureCalculator");
//enable metadata
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
myServiceHost.Description.Behaviors.Add(smb);
myServiceHost.Open();
Console.WriteLine("Listening");
Console.WriteLine("Press Enter to close the service");
Console.ReadLine();
myServiceHost.Close();
}
}
[ServiceContract]
public interface ICalculator
{
[OperationContract]
double Add(double a, double b);
}
public class Calculator : ICalculator
{
public double Add(double a, double b)
{
return a + b;
}
}
}
另請參閱
工作
HOW TO:建立 Windows Communication Foundation 用戶端