Sdílet prostřednictvím


Zabezpečení zpráv u klienta Windows bez vyjednávání pověření

Následující scénář ukazuje klienta a službu WCF (Windows Communication Foundation) zabezpečenou protokolem Kerberos.

Služba i klient jsou ve stejné doméně nebo důvěryhodné doméně.

Poznámka:

Rozdíl mezi tímto scénářem a zabezpečením zpráv pomocí klienta systému Windows spočívá v tom, že tento scénář nevyjednává přihlašovací údaje služby se službou před odesláním zprávy aplikace. Vzhledem k tomu, že to vyžaduje protokol Kerberos, tento scénář navíc vyžaduje prostředí domény systému Windows.

Zabezpečení zpráv bez vyjednávání přihlašovacích údajů

Charakteristika Popis
Režim zabezpečení Zpráva
Vzájemná funkční spolupráce Ano, WS-Security s klienty kompatibilními s tokeny Kerberos
Ověřování (server) Vzájemné ověřování serveru a klienta
Ověřování (klient) Vzájemné ověřování serveru a klienta
Integrita Ano
Důvěrnost Ano
Přeprava HTTP
Vazba WSHttpBinding

Služba

Následující kód a konfigurace se mají spouštět nezávisle. Proveďte některou z následujících akcí:

  • Vytvořte samostatnou službu pomocí kódu bez konfigurace.

  • Vytvořte službu pomocí zadané konfigurace, ale nedefinujte žádné koncové body.

Kód

Následující kód vytvoří koncový bod služby, který používá zabezpečení zpráv. Kód zakáže vyjednávání přihlašovacích údajů služby a zřízení tokenu kontextu zabezpečení (SCT).

Poznámka:

Pokud chcete použít typ přihlašovacích údajů systému Windows bez vyjednávání, musí mít uživatelský účet služby přístup k hlavnímu názvu služby (SPN), který je zaregistrovaný v doméně služby Active Directory. Můžete to udělat dvěma způsoby:

  1. NetworkService Ke spuštění služby použijte účet nebo LocalSystem účet. Vzhledem k tomu, že tyto účty mají přístup k hlavnímu názvu služby (SPN) počítače, který se naváže při připojení počítače k doméně služby Active Directory, wcf automaticky vygeneruje správný prvek SPN uvnitř koncového bodu služby v metadatech služby (jazyk popisu webových služeb nebo WSDL).

  2. Ke spuštění služby použijte libovolný účet domény služby Active Directory. V takovém případě musíte vytvořit hlavní název služby (SPN) pro tento účet domény. Jedním ze způsobů, jak to udělat, je použít nástroj Setspn.exe nástroj. Po vytvoření hlavního názvu služby pro účet služby nakonfigurujte WCF tak, aby tento hlavní název služby publikoval do klientů služby prostřednictvím jeho metadat (WSDL). To se provádí nastavením identity koncového bodu pro vystavený koncový bod, a to buď prostřednictvím konfiguračního souboru aplikace nebo kódu. Následující příklad publikuje identitu programově.

Další informace o hlavních nástavcích služby, protokolu Kerberos a službě Active Directory naleznete v technickém dodatku Kerberos pro Windows. Další informace o identitách koncových bodů najdete v tématu Režimy ověřování 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()

Konfigurace

Místo kódu je možné použít následující konfiguraci.

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

Klient

Následující kód a konfigurace se mají spouštět nezávisle. Proveďte některou z následujících akcí:

  • Vytvořte samostatného klienta pomocí kódu (a klientského kódu).

  • Vytvořte klienta, který nedefinuje žádné adresy koncových bodů. Místo toho použijte konstruktor klienta, který přebírá název konfigurace jako argument. Příklad:

    CalculatorClient cc = new CalculatorClient("EndpointConfigurationName");
    
    Dim cc As New CalculatorClient("EndpointConfigurationName")
    

Kód

Následující kód nakonfiguruje klienta. Režim zabezpečení je nastavený na Zprávu a typ přihlašovacích údajů klienta je nastavený na Windows. Všimněte si, že NegotiateServiceCredential vlastnosti a EstablishSecurityContext vlastnosti jsou nastaveny na false.

Poznámka:

Pokud chcete použít typ přihlašovacích údajů systému Windows bez vyjednávání, musí být klient před zahájením komunikace se službou nakonfigurovaný s hlavním názvem služby s účtem služby. Klient pomocí hlavního názvu služby získá token Kerberos k ověření a zabezpečení komunikace se službou. Následující ukázka ukazuje, jak nakonfigurovat klienta s hlavním názvem služby. Pokud k vygenerování klienta používáte nástroj ServiceModel Metadata Utility (Svcutil.exe), hlavní název služby se automaticky rozšíří do klienta z metadat služby (WSDL), pokud metadata služby obsahují dané informace. Další informace o tom, jak službu nakonfigurovat tak, aby zahrnovala její hlavní název služby v metadatech služby, najdete v části Služba dále v tomto tématu.

Další informace o hlavních nástavcích služby, Protokolu Kerberos a Active Directory naleznete v technickém dodatku Kerberos pro Windows. Další informace o identitách koncových bodů najdete v tématu Režimy ověřování 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

Konfigurace

Následující kód nakonfiguruje klienta. Všimněte si, že <element servicePrincipalName> musí být nastaven tak, aby odpovídal hlavnímu názvu služby jako zaregistrovaný pro účet služby v doméně služby Active Directory.

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

Viz také