Nasıl yapılır: Windows Kimlik Bilgileri ile Bir Hizmeti Güvenli Hale Getirme
Bu konuda, bir Windows etki alanında bulunan ve aynı etki alanındaki istemciler tarafından çağrılan bir Windows Communication Foundation (WCF) hizmetinde aktarım güvenliğinin nasıl etkinleştirileceği gösterilmektedir. Bu senaryo hakkında daha fazla bilgi için bkz . Windows Kimlik Doğrulaması ile Aktarım Güvenliği. Örnek uygulama için bkz . WSHttpBinding örneği.
Bu konu başlığında, zaten tanımlanmış bir sözleşme arabiriminiz ve uygulamanız olduğu varsayılır ve buna eklenir. Ayrıca mevcut bir hizmeti ve istemciyi de değiştirebilirsiniz.
Windows kimlik bilgileriyle bir hizmetin güvenliğini tamamen kod içinde sağlayabilirsiniz. Alternatif olarak, yapılandırma dosyası kullanarak kodun bir bölümünü atlayabilirsiniz. Bu konu her iki yolu da gösterir. Her ikisini birden değil, yalnızca bir yolu kullandığınızdan emin olun.
İlk üç yordam, kodu kullanarak hizmetin güvenliğini sağlamayı gösterir. Dördüncü ve beşinci yordam, yapılandırma dosyasıyla nasıl yapılacağını gösterir.
Kod Kullanma
Hizmet ve istemcinin tam kodu bu konunun sonundaki Örnek bölümündedir.
İlk yordam, kodda sınıf WSHttpBinding oluşturma ve yapılandırma adımlarını gösterir. Bağlama HTTP aktarımını kullanır. İstemcide aynı bağlama kullanılır.
Windows kimlik bilgilerini ve ileti güvenliğini kullanan bir WSHttpBinding oluşturmak için
Bu yordamın kodu, Örnek bölümündeki hizmet kodunda sınıfının yönteminin
Test
başınaRun
eklenir.Öğesinin bir örneğini oluşturur WSHttpBinding sınıfı.
Mode sınıfının özelliğini WSHttpSecurity olarak Messageayarlayın.
ClientCredentialType sınıfının özelliğini MessageSecurityOverHttp olarak Windowsayarlayın.
Bu yordamın kodu aşağıdaki gibidir:
// 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;
Dim myBinding As New WSHttpBinding() myBinding.Security.Mode = SecurityMode.Message myBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
Hizmette Bağlamayı Kullanma
Bu, bağlamanın şirket içinde barındırılan bir hizmette nasıl kullanılacağını gösteren ikinci yordamdır. Barındırma hizmetleri hakkında daha fazla bilgi için bkz . Barındırma Hizmetleri.
Hizmette bağlama kullanmak için
Bu yordamın kodunu önceki yordamdaki kodun arkasına ekleyin.
adlı
contractType
bir Type değişken oluşturun ve arabiriminin türünü ()ICalculator
atayın. Visual Basic kullanırken işleciniGetType
kullanın; C# kullanırken anahtar sözcüğünütypeof
kullanın.adlı
serviceType
ikinci Type bir değişken oluşturun ve uygulanan sözleşmenin (Calculator
) türünü atayın.Hizmetin temel adresiyle adlı
baseAddress
sınıfın bir örneğini Uri oluşturun. Temel adres, aktarımla eşleşen bir şemaya sahip olmalıdır. Bu durumda, aktarım düzeni HTTP'dir ve adres özel Tekdüzen Kaynak Tanımlayıcısı (URI) "localhost" ve bir bağlantı noktası numarası (8036) ile bir temel uç nokta adresi ("serviceModelSamples/):http://localhost:8036/serviceModelSamples/
içerir.ve
baseAddress
değişkenleriyle sınıfının bir örneğini ServiceHostserviceType
oluşturun., bağlamasını ve uç nokta adını (secureCalculator) kullanarak
contractType
hizmete bir uç nokta ekleyin. İstemci, hizmete çağrı başlatırken temel adresi ve uç nokta adını birleştirmelidir.Open Hizmeti başlatmak için yöntemini çağırın. Bu yordamın kodu burada gösterilmiştir:
// 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("http://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();
' 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("http://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()
İstemcide Bağlamayı Kullanma
Bu yordam, hizmetle iletişim kuran bir ara sunucu oluşturmayı gösterir. Proxy, proxy'yi oluşturmak için hizmet meta verilerini kullanan ServiceModel Meta Veri Yardımcı Programı Aracı (Svcutil.exe) ile oluşturulur.
Bu yordam ayrıca hizmetle iletişim kurmak için sınıfının bir örneğini WSHttpBinding oluşturur ve ardından hizmeti çağırır.
Bu örnekte istemciyi oluşturmak için yalnızca kod kullanılmaktadır. Alternatif olarak, bu yordamın sonraki bölümünde gösterilen bir yapılandırma dosyası kullanabilirsiniz.
İstemcide bir bağlamayı kodla kullanmak için
Hizmetin meta verilerinden ara sunucu kodu oluşturmak için SvcUtil.exe aracını kullanın. Daha fazla bilgi için bkz . Nasıl yapılır: İstemci Oluşturma. Oluşturulan ara sunucu kodu sınıfından ClientBase<TChannel> devralır ve bu sayede her istemcinin bir WCF hizmetiyle iletişim kurmak için gerekli oluşturuculara, yöntemlere ve özelliklere sahip olmasını sağlar. Bu örnekte, oluşturulan kod arabirimi uygulayarak
CalculatorClient
ICalculator
hizmet koduyla uyumluluğu sağlayan sınıfını içerir.Bu yordamın kodu, istemci programının yönteminin başına
Main
eklenir.sınıfının bir örneğini WSHttpBinding oluşturun ve güvenlik modunu
Message
olarak, istemci kimlik bilgisi türünü olarakWindows
ayarlayın. Örnek değişkeniniclientBinding
olarak adlandırın.adlı
serviceAddress
sınıfın EndpointAddress bir örneğini oluşturun. Örneği, uç nokta adıyla birleştirilmiş temel adresle başlatın.ve değişkenleriyle
serviceAddress
oluşturulan istemci sınıfının bir örneğiniclientBinding
oluşturun.Aşağıdaki kodda Open gösterildiği gibi yöntemini çağırın.
Hizmeti çağırın ve sonuçları görüntüleyin.
// 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();
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")
Yapılandırma Dosyasını Kullanma
Yordam koduyla bağlama oluşturmak yerine, yapılandırma dosyasının bağlamalar bölümü için gösterilen aşağıdaki kodu kullanabilirsiniz.
Henüz tanımlanmış bir hizmetiniz yoksa bkz. Hizmetleri Tasarlama ve Uygulama ve Hizmetleri Yapılandırma.
Not
Bu yapılandırma kodu hem hizmet hem de istemci yapılandırma dosyalarında kullanılır.
Yapılandırmayı kullanarak Windows etki alanındaki bir hizmette aktarım güvenliğini etkinleştirmek için
Yapılandırma dosyasının bindings öğesi bölümüne bir <wsHttpBinding>> öğesi ekleyin.<
öğesine bir
<binding>
öğe<WSHttpBinding>
ekleyin ve özniteliğini uygulamanıza uygun bir değere ayarlayınconfigurationName
.Bir
<security>
öğe ekleyin ve özniteliğinimode
İleti olarak ayarlayın.Bir
<message>
öğe ekleyin ve özniteliğiniclientCredentialType
Windows olarak ayarlayın.Hizmetin yapılandırma dosyasında bölümünü
<bindings>
aşağıdaki kodla değiştirin. Henüz bir hizmet yapılandırma dosyanız yoksa bkz . Hizmetleri ve İstemcileri Yapılandırmak için Bağlamaları Kullanma.<bindings> <wsHttpBinding> <binding name = "wsHttpBinding_Calculator"> <security mode="Message"> <message clientCredentialType="Windows"/> </security> </binding> </wsHttpBinding> </bindings>
İstemcide Bağlamayı Kullanma
Bu yordamda iki dosyanın nasıl oluşturulacağı gösterilmektedir: hizmetle iletişim kuran bir ara sunucu ve bir yapılandırma dosyası. Ayrıca, istemcide kullanılan üçüncü dosya olan istemci programında yapılan değişiklikleri de açıklar.
Yapılandırmaya sahip bir istemcide bağlama kullanmak için
Hizmetin meta verilerinden ara sunucu kodunu ve yapılandırma dosyasını oluşturmak için SvcUtil.exe aracını kullanın. Daha fazla bilgi için bkz . Nasıl yapılır: İstemci Oluşturma.
Oluşturulan yapılandırma dosyasının <bağlamalar> bölümünü önceki bölümde yer alan yapılandırma koduyla değiştirin.
Yordam kodu, istemci programının yönteminin
Main
başına eklenir.Yapılandırma dosyasındaki bağlamanın adını giriş parametresi olarak geçirerek oluşturulan istemci sınıfının bir örneğini oluşturun.
Aşağıdaki kodda Open gösterildiği gibi yöntemini çağırın.
Hizmeti çağırın ve sonuçları görüntüleyin.
// 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();
Örnek
using System;
using System.Collections;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
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("http://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;
}
}
}
using System;
using System.Collections.Generic;
using System.ServiceModel;
namespace Client
{
static class SecureClientCode
{
static void Main()
{
// 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();
}
static void Main2()
{
// 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();
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples", ConfigurationName = "ICalculator")]
public interface ICalculator
{
[System.ServiceModel.OperationContractAttribute(Action = "http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction = "http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")]
double Add(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(Action = "http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction = "http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")]
double Subtract(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(Action = "http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction = "http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")]
double Multiply(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(Action = "http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction = "http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")]
double Divide(double n1, double n2);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface ICalculatorChannel : ICalculator, System.ServiceModel.IClientChannel
{
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public class CalculatorClient : System.ServiceModel.ClientBase<ICalculator>, ICalculator
{
public CalculatorClient()
{
}
public CalculatorClient(string endpointConfigurationName)
:
base(endpointConfigurationName)
{
}
public CalculatorClient(string endpointConfigurationName, string remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
public CalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
public CalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress)
:
base(binding, remoteAddress)
{
}
public double Add(double n1, double n2)
{
return base.Channel.Add(n1, n2);
}
public double Subtract(double n1, double n2)
{
return base.Channel.Subtract(n1, n2);
}
public double Multiply(double n1, double n2)
{
return base.Channel.Multiply(n1, n2);
}
public double Divide(double n1, double n2)
{
return base.Channel.Divide(n1, n2);
}
}
}
Imports System.Collections.Generic
Imports System.ServiceModel
Public Class Program
Shared Sub Main()
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")
End Sub
End Class
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0"), System.ServiceModel.ServiceContractAttribute([Namespace]:="http://Microsoft.ServiceModel.Samples", ConfigurationName:="ICalculator")> _
Public Interface ICalculator
<System.ServiceModel.OperationContractAttribute(Action:="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction:="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")> _
Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
<System.ServiceModel.OperationContractAttribute(Action:="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction:="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")> _
Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
<System.ServiceModel.OperationContractAttribute(Action:="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction:="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")> _
Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
<System.ServiceModel.OperationContractAttribute(Action:="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction:="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")> _
Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
End Interface 'ICalculator
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")> _
Public Interface ICalculatorChannel
: Inherits ICalculator, System.ServiceModel.IClientChannel
End Interface 'ICalculatorChannel
<System.Diagnostics.DebuggerStepThroughAttribute(), System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")> _
Public Class CalculatorClient
Inherits System.ServiceModel.ClientBase(Of ICalculator)
Implements ICalculator
Public Sub New()
'
End Sub
Public Sub New(ByVal endpointConfigurationName As String)
MyBase.New(endpointConfigurationName)
End Sub
Public Sub New(ByVal endpointConfigurationName As String, ByVal remoteAddress As String)
MyBase.New(endpointConfigurationName, remoteAddress)
End Sub
Public Sub New(ByVal endpointConfigurationName As String, ByVal remoteAddress As System.ServiceModel.EndpointAddress)
MyBase.New(endpointConfigurationName, remoteAddress)
End Sub
Public Sub New(ByVal binding As System.ServiceModel.Channels.Binding, ByVal remoteAddress As System.ServiceModel.EndpointAddress)
MyBase.New(binding, remoteAddress)
End Sub
Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
Return MyBase.Channel.Add(n1, n2)
End Function 'Add
Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
Return MyBase.Channel.Subtract(n1, n2)
End Function 'Subtract
Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
Return MyBase.Channel.Multiply(n1, n2)
End Function 'Multiply
Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
Return MyBase.Channel.Divide(n1, n2)
End Function 'Divide
End Class