Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Toto téma popisuje základní programovací úlohy používané k vytvoření zabezpečené aplikace WCF (Windows Communication Foundation). Toto téma se zabývá pouze ověřováním, důvěrností a integritou, které se souhrnně označuje jako zabezpečení přenosu. Toto téma se nevztahuje na autorizaci (řízení přístupu k prostředkům nebo službám); informace o autorizaci naleznete v tématu Autorizace.
Poznámka:
Cenný úvod do konceptů zabezpečení, zejména pokud jde o WCF, najdete v sadě vzorů a kurzů postupů na webu MSDN ve scénářích, vzorech a pokynech k implementaci pro vylepšení webových služeb (WSE) 3.0.
Programování zabezpečení WCF je založeno na třech krocích nastavení: režim zabezpečení, typ přihlašovacích údajů klienta a hodnoty přihlašovacích údajů. Tyto kroky můžete provést prostřednictvím kódu nebo konfigurace.
Nastavení režimu zabezpečení
Níže jsou vysvětleny obecné kroky pro programování s režimem zabezpečení ve WCF:
Vyberte jednu z předdefinovaných vazeb odpovídajících požadavkům vaší aplikace. Seznam možností vazby najdete v tématu System-Provided Vazby. Ve výchozím nastavení má téměř každá vazba povolené zabezpečení. Jedinou výjimkou je BasicHttpBinding třída (při použití konfigurace < basicHttpBinding>).
Vazbu, kterou vyberete, určuje přenos. Například WSHttpBinding jako přenos používá protokol HTTP. NetTcpBinding Používá protokol TCP.
Vyberte jeden z režimů zabezpečení pro vazbu. Všimněte si, že výběr vazby určuje dostupné možnosti režimu. Například WSDualHttpBinding nepovoluje zabezpečení přenosu (není to možnost). Podobně ani MsmqIntegrationBindingNetNamedPipeBinding zabezpečení zpráv neumožňuje.
Máte tři možnosti:
TransportZabezpečení přenosu závisí na mechanismu, který používá vámi vybraná vazba. Pokud například používáte
WSHttpBinding, je bezpečnostní mechanismus ssl (Secure Sockets Layer) (také mechanismus protokolu HTTPS). Obecně řečeno, hlavní výhodou zabezpečení přenosu je, že zajišťuje dobrou propustnost bez ohledu na to, který přenos používáte. Má však dvě omezení: První je, že transportní mechanismus určuje typ přihlašovacích údajů použitý k ověření uživatele. To je nevýhoda pouze v případě, že služba potřebuje spolupracovat s dalšími službami, které vyžadují různé typy přihlašovacích údajů. Druhým je to, že protože zabezpečení není použito na úrovni zpráv, zabezpečení se implementuje způsobem krok za krokem, nikoli koncovým. Toto druhé omezení je problém pouze v případě, že cesta zprávy mezi klientem a službou zahrnuje zprostředkovatele. Další informace o tom, kterou dopravu použít, naleznete v tématu Volba přenosu. Další informace o použití zabezpečení přenosu naleznete v tématu Přehled zabezpečení přenosu.MessageZabezpečení zpráv znamená, že každá zpráva obsahuje potřebná záhlaví a data, aby byla zpráva zabezpečená. Vzhledem k tomu, že složení hlaviček se liší, můžete zahrnout libovolný počet přihlašovacích údajů. To se stane faktorem, pokud spolupracujete s jinými službami, které vyžadují konkrétní typ přihlašovacích údajů, který nemůže dodat transportní mechanismus, nebo pokud se zpráva musí použít s více než jednou službou, kde každá služba vyžaduje jiný typ přihlašovacích údajů.
Další informace naleznete v tématu Zabezpečení zpráv.
TransportWithMessageCredentialTato volba používá přenosovou vrstvu k zabezpečení přenosu zpráv, zatímco každá zpráva obsahuje bohaté přihlašovací údaje, které ostatní služby potřebují. To kombinuje výhodu výkonu zabezpečení přenosu s výhodou bohatosti přihlašovacích údajů zabezpečení zpráv. Tato možnost je k dispozici s následujícími vazbami: BasicHttpBinding, WSFederationHttpBindingNetPeerTcpBinding, a WSHttpBinding.
Pokud se rozhodnete použít zabezpečení přenosu pro protokol HTTP (jinými slovy HTTPS), musíte také nakonfigurovat hostitele s certifikátem SSL a povolit SSL na portu. Další informace naleznete v tématu zabezpečení přenosu HTTP.
Pokud používáte WSHttpBinding a nepotřebujete vytvořit zabezpečenou relaci, nastavte EstablishSecurityContext vlastnost na
false.Zabezpečená relace nastane, když klient a služba vytvoří kanál pomocí symetrického klíče (klient i server používají stejný klíč pro délku konverzace, dokud se dialogové okno neskončí).
Nastavení typu přihlašovacích údajů klienta
Podle potřeby vyberte typ přihlašovacích údajů klienta. Další informace naleznete v tématu Výběr typu přihlašovacích údajů. K dispozici jsou následující typy přihlašovacích údajů klienta:
WindowsCertificateDigestBasicUserNameNTLMIssuedToken
V závislosti na tom, jak režim nastavíte, musíte nastavit typ přihlašovacích údajů. Pokud jste například vybrali wsHttpBindinga nastavili režim na "Zpráva", můžete také nastavit clientCredentialType atribut prvku Message na jednu z následujících hodnot: None, , Windows, UserNameCertificate, a IssuedToken, jak je znázorněno v následujícím příkladu konfigurace.
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="myBinding">
<security mode="Message"/>
<message clientCredentialType="Windows"/>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
Nebo v kódu:
WSHttpBinding b = new WSHttpBinding();
b.Name = "myBinding";
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType=MessageCredentialType.Windows;
Dim b As New WSHttpBinding()
b.Name = "myBinding"
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows
Nastavení hodnot přihlašovacích údajů služby
Jakmile vyberete typ přihlašovacích údajů klienta, musíte nastavit skutečné přihlašovací údaje pro službu a klienta, které se mají použít. Ve službě jsou přihlašovací údaje nastaveny pomocí třídy ServiceCredentials a vráceny vlastností Credentials třídy ServiceHostBase. Použitá vazba znamená typ přihlašovacích údajů služby, zvolený režim zabezpečení a typ přihlašovacích údajů klienta. Následující kód nastaví certifikát pro přihlašovací údaje služby.
// Create the binding for an endpoint.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;
// Create the ServiceHost for a calculator.
Uri baseUri = new Uri("net.tcp://MachineName/tcpBase");
Uri[] baseAddresses = new Uri[] { baseUri };
ServiceHost sh = new ServiceHost(typeof(Calculator), baseAddresses);
// Add an endpoint using the binding and a new address.
Type c = typeof(ICalculator);
sh.AddServiceEndpoint(c, b, "MyEndpoint");
// Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine,
StoreName.My,
X509FindType.FindBySubjectName,
"client.com");
try
{
sh.Open();
Console.WriteLine("Listening....");
Console.ReadLine();
sh.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine($"A communication error occurred: {ce.Message}");
Console.WriteLine();
}
catch (System.Exception exc)
{
Console.WriteLine($"An unforeseen error occurred: {exc.Message}");
Console.ReadLine();
}
' Create the binding for an endpoint.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message
' Create the ServiceHost for a calculator.
Dim baseUri As New Uri("net.tcp://MachineName/tcpBase")
Dim baseAddresses() As Uri = {baseUri}
Dim sh As New ServiceHost(GetType(Calculator), baseAddresses)
' Add an endpoint using the binding and a new address.
Dim c As Type = GetType(ICalculator)
sh.AddServiceEndpoint(c, b, "MyEndpoint")
' Set a certificate as the credential for the service.
sh.Credentials.ServiceCertificate.SetCertificate( _
StoreLocation.LocalMachine, _
StoreName.My, _
X509FindType.FindBySubjectName, _
"contoso.com")
Try
sh.Open()
Console.WriteLine("Listening....")
Console.ReadLine()
sh.Close()
Catch ce As CommunicationException
Console.WriteLine("A communication error occurred: {0}", ce.Message)
Console.WriteLine()
Catch exc As System.Exception
Console.WriteLine("An unforeseen error occurred: {0}", exc.Message)
Console.ReadLine()
End Try
Nastavení hodnot přihlašovacích údajů klienta
V klientovi nastavte hodnoty přihlašovacích údajů klienta pomocí ClientCredentials třídy a vrácené ClientCredentials vlastností ClientBase<TChannel> třídy. Následující kód nastaví certifikát jako přihlašovací údaje klienta pomocí protokolu TCP.
// Create a NetTcpBinding and set its security properties. The
// security mode is Message, and the client must be authenticated with
// Windows. Therefore the client must be on the same Windows domain.
NetTcpBinding b = new NetTcpBinding();
b.Security.Mode = SecurityMode.Message;
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
// Set a Type variable for use when constructing the endpoint.
Type c = typeof(ICalculator);
// Create a base address for the service.
Uri tcpBaseAddress =
new Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName");
// The base address is in an array of URI objects.
Uri[] baseAddresses = new Uri[] { tcpBaseAddress };
// Create the ServiceHost with type and base addresses.
ServiceHost sh = new ServiceHost(typeof(CalculatorClient), baseAddresses);
// Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "");
sh.Open();
string address = sh.Description.Endpoints[0].ListenUri.AbsoluteUri;
Console.WriteLine($"Listening @ {address}");
Console.WriteLine("Press enter to close the service");
Console.ReadLine();
' Create a NetTcpBinding and set its security properties. The
' security mode is Message, and the client must be authenticated with
' Windows. Therefore the client must be on the same Windows domain.
Dim b As New NetTcpBinding()
b.Security.Mode = SecurityMode.Message
b.Security.Message.ClientCredentialType = MessageCredentialType.Windows
' Set a Type variable for use when constructing the endpoint.
Dim c As Type = GetType(ICalculator)
' Create a base address for the service.
Dim tcpBaseAddress As New Uri("net.tcp://machineName.Domain.Contoso.com:8036/serviceName")
' The base address is in an array of URI objects.
Dim baseAddresses() As Uri = {tcpBaseAddress}
' Create the ServiceHost with type and base addresses.
Dim sh As New ServiceHost(GetType(CalculatorClient), baseAddresses)
' Add an endpoint to the service using the service type and binding.
sh.AddServiceEndpoint(c, b, "")
sh.Open()
Dim address As String = sh.Description.Endpoints(0).ListenUri.AbsoluteUri
Console.WriteLine("Listening @ {0}", address)
Console.WriteLine("Press enter to close the service")
Console.ReadLine()