Sdílet prostřednictvím


Postupy: Zabezpečení služby pomocí přihlašovacích údajů Windows

Toto téma ukazuje, jak povolit zabezpečení přenosu ve službě WCF (Windows Communication Foundation), která se nachází v doméně Windows a volá se klienty ve stejné doméně. Další informace o tomto scénáři naleznete v tématu Zabezpečení přenosu s ověřováním systému Windows. Ukázkovou aplikaci najdete v ukázce WSHttpBinding .

V tomto tématu se předpokládá, že už máte definované existující rozhraní kontraktů a implementaci a přidává se k němu. Můžete také upravit existující službu a klienta.

Službu můžete zabezpečit pomocí přihlašovacích údajů systému Windows zcela v kódu. Případně můžete některé kódy vynechat pomocí konfiguračního souboru. Toto téma ukazuje oba způsoby. Ujistěte se, že používáte jenom jeden ze způsobů, ne oba.

První tři postupy ukazují, jak zabezpečit službu pomocí kódu. Čtvrtý a pátý postup ukazuje, jak to udělat s konfiguračním souborem.

Použití kódu

Úplný kód pro službu a klient je v části Příklad na konci tohoto tématu.

První postup vás provede vytvořením a konfigurací WSHttpBinding třídy v kódu. Vazba používá přenos HTTP. Stejná vazba se používá v klientovi.

Vytvoření wsHttpBinding, který používá přihlašovací údaje Windows a zabezpečení zpráv

  1. Kód této procedury se vloží na začátek Run metody Test třídy v kódu služby v části Příklad.

  2. Vytvořit instanci WSHttpBinding třídy.

  3. Mode Nastavte vlastnost WSHttpSecurity třídy na Message.

  4. ClientCredentialType Nastavte vlastnost MessageSecurityOverHttp třídy na Windows.

  5. Kód pro tento postup je následující:

    // 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
    

Použití vazby ve službě

Toto je druhý postup, který ukazuje, jak používat vazbu ve službě v místním prostředí. Další informace o hostitelských službách naleznete v tématu Hostitelské služby.

Použití vazby ve službě
  1. Vložte kód tohoto postupu za kód z předchozího postupu.

  2. Vytvořte proměnnou Type s názvem contractType a přiřaďte jí typ rozhraní (ICalculator). Při použití jazyka GetType Visual Basic použijte operátor; při použití jazyka typeof C# použijte klíčové slovo.

  3. Vytvořte druhou Type proměnnou s názvem serviceType a přiřaďte jí typ implementovaného kontraktu (Calculator).

  4. Vytvořte instanci Uri třídy s názvem baseAddress základní adresou služby. Základní adresa musí mít schéma, které odpovídá přenosu. V tomto případě je schéma přenosu HTTP a adresa obsahuje speciální identifikátor URI (Uniform Resource Identifier) "localhost" a číslo portu (8036) a také adresu základního koncového bodu ("serviceModelSamples/): http://localhost:8036/serviceModelSamples/.

  5. Vytvořte instanci ServiceHost třídy s serviceType proměnnými.baseAddress

  6. Přidejte do služby koncový bod pomocí vazby contractType, a názvu koncového bodu (secureCalculator). Klient musí při zahájení volání služby zřetězí základní adresu a název koncového bodu.

  7. Open Voláním metody spusťte službu. Zde je uvedený kód pro tento postup:

    // 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()
    

Použití vazby v klientovi

Tento postup ukazuje, jak vygenerovat proxy server, který komunikuje se službou. Proxy server se vygeneruje pomocí nástroje ServiceModel Metadata Utility (Svcutil.exe), který k vytvoření proxy serveru používá metadata služby.

Tento postup také vytvoří instanci WSHttpBinding třídy pro komunikaci se službou a potom zavolá službu.

Tento příklad používá pouze kód k vytvoření klienta. Jako alternativu můžete použít konfigurační soubor, který je uvedený v následující části tohoto postupu.

Použití vazby v klientovi s kódem

  1. Pomocí nástroje SvcUtil.exe vygenerujte kód proxy z metadat služby. Další informace naleznete v tématu Postupy: Vytvoření klienta. Vygenerovaný proxy kód dědí z ClientBase<TChannel> třídy, což zajišťuje, že každý klient má nezbytné konstruktory, metody a vlastnosti ke komunikaci se službou WCF. V tomto příkladu vygenerovaný kód obsahuje CalculatorClient třídu, která implementuje ICalculator rozhraní, což umožňuje kompatibilitu s kódem služby.

  2. Kód tohoto postupu se vloží na začátek Main metody klientského programu.

  3. Vytvořte instanci WSHttpBinding třídy a nastavte její režim zabezpečení na Message typ přihlašovacích údajů klienta na Windows. Příklad pojmenuje proměnnou clientBinding.

  4. Vytvořte instanci EndpointAddress třídy s názvem serviceAddress. Inicializace instance se zřetězeným základní adresou s názvem koncového bodu.

  5. Vytvořte instanci vygenerované klientské třídy s serviceAddress proměnnými.clientBinding

  6. Volejte metodu Open , jak je znázorněno v následujícím kódu.

  7. Zavolejte službu a zobrazte výsledky.

    // 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")
    

Použití konfiguračního souboru

Místo vytvoření vazby s procedurálním kódem můžete použít následující kód zobrazený pro sekci vazeb konfiguračního souboru.

Pokud ještě nemáte definovanou službu, přečtěte si téma Návrh a implementace služeb a Konfigurace služeb.

Poznámka:

Tento konfigurační kód se používá v konfiguračních souborech služby i klienta.

Povolení zabezpečení přenosu ve službě v doméně Windows pomocí konfigurace

  1. <Přidejte element wsHttpBinding> do oddílu <elementu bindings> konfiguračního souboru.

  2. Přidejte do elementu <binding> <WSHttpBinding> prvek a nastavte configurationName atribut na hodnotu odpovídající vaší aplikaci.

  3. <security> Přidejte prvek a nastavte mode atribut na Message.

  4. <message> Přidejte prvek a nastavte clientCredentialType atribut na Windows.

  5. V konfiguračním souboru služby nahraďte <bindings> část následujícím kódem. Pokud ještě nemáte konfigurační soubor služby, přečtěte si téma Použití vazeb ke konfiguraci služeb a klientů.

    <bindings>
      <wsHttpBinding>
       <binding name = "wsHttpBinding_Calculator">
         <security mode="Message">
           <message clientCredentialType="Windows"/>
         </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    

Použití vazby v klientovi

Tento postup ukazuje, jak vygenerovat dva soubory: proxy server, který komunikuje se službou a konfiguračním souborem. Popisuje také změny klientského programu, což je třetí soubor použitý v klientovi.

Použití vazby v klientovi s konfigurací

  1. Pomocí nástroje SvcUtil.exe vygenerujte z metadat služby proxy kód a konfigurační soubor. Další informace naleznete v tématu Postupy: Vytvoření klienta.

  2. <Oddíl vazeb> vygenerovaného konfiguračního souboru nahraďte konfiguračním kódem z předchozí části.

  3. Procedurální kód se vloží na začátek Main metody klientského programu.

  4. Vytvořte instanci vygenerované třídy klienta, která předává název vazby v konfiguračním souboru jako vstupní parametr.

  5. Volejte metodu Open , jak je znázorněno v následujícím kódu.

  6. Zavolejte službu a zobrazte výsledky.

    // 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();
    

Příklad

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

Viz také