Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cette rubrique décrit les tâches de programmation fondamentales utilisées pour créer une application Windows Communication Foundation (WCF) sécurisée. Cette rubrique couvre uniquement l’authentification, la confidentialité et l’intégrité, collectivement appelée sécurité de transfert. Cette rubrique ne couvre pas l’autorisation (contrôle de l’accès aux ressources ou aux services) ; pour plus d’informations sur l’autorisation, consultez Autorisation.
Remarque
Pour une introduction précieuse aux concepts de sécurité, en particulier en ce qui concerne WCF, consultez l’ensemble de tutoriels sur les modèles et pratiques sur MSDN dans les scénarios, les modèles et les conseils d’implémentation pour les améliorations des services web (WSE) 3.0.
La programmation de la sécurité WCF est basée sur trois étapes définissant les éléments suivants : le mode de sécurité, un type d’informations d’identification client et les valeurs d’informations d’identification. Vous pouvez effectuer ces étapes par le biais du code ou de la configuration.
Définition du mode de sécurité
Voici les étapes générales à suivre pour la programmation avec le mode de sécurité dans WCF :
Sélectionnez l’une des liaisons prédéfinies appropriées aux exigences de votre application. Pour obtenir la liste des choix de liaisons, consultez Liaisons fournies par le système. Par défaut, presque chaque liaison a la sécurité activée. L’une des exceptions est la classe BasicHttpBinding (à l’aide de la configuration, <basicHttpBinding>).
La liaison que vous sélectionnez détermine le transport. Par exemple, WSHttpBinding utilise HTTP comme transport ; NetTcpBinding utilise TCP.
Sélectionnez l'un des modes de sécurité disponibles pour la liaison. Notez que la liaison que vous sélectionnez détermine les choix de mode disponible. Par exemple, la liaison WSDualHttpBinding ne permet pas de définir le niveau transport comme mode de sécurité (ce mode n'est pas disponible pour cette liaison). De même, ni le MsmqIntegrationBinding ni le NetNamedPipeBinding ne permettent la sécurité des messages.
Trois choix sont possibles :
Transport
La sécurité du transport dépend du mécanisme utilisé par la liaison que vous avez sélectionnée. Par exemple, si vous utilisez
WSHttpBinding
alors le mécanisme de sécurité est SSL (Secure Sockets Layer) (également le mécanisme pour le protocole HTTPS). En règle générale, le principal avantage de la sécurité du transport est qu’il offre un débit correct, quel que soit le transport que vous utilisez. Toutefois, il présente deux limitations : le premier est que le mécanisme de transport détermine le type d’informations d’identification utilisé pour authentifier un utilisateur. Cela est un inconvénient uniquement si un service doit interagir avec d’autres services qui demandent différents types d’informations d’identification. La seconde est que, étant donné que la sécurité n’est pas appliquée au niveau du message, la sécurité est implémentée de manière hop-by-hop plutôt que de bout en bout. Cette dernière limitation est un problème uniquement si le chemin du message entre le client et le service inclut des intermédiaires. Pour plus d’informations sur le transport à utiliser, consultez Choix d’un transport. Pour plus d’informations sur l’utilisation de la sécurité du transport, consultez Vue d’ensemble de la sécurité des transports.Message
La sécurité des messages signifie que chaque message inclut les en-têtes et données nécessaires pour sécuriser le message. Étant donné que la composition des en-têtes varie, vous pouvez inclure n’importe quel nombre d’informations d’identification. Cela devient un facteur si vous interagissez avec d’autres services qui demandent un type d’informations d’identification spécifique qu’un mécanisme de transport ne peut pas fournir, ou si le message doit être utilisé avec plusieurs services, où chaque service exige un type d’informations d’identification différent.
Pour plus d’informations, consultez Sécurité des messages.
TransportWithMessageCredential
Ce choix utilise la couche de transport pour sécuriser le transfert de messages, tandis que chaque message inclut les informations d’identification enrichies dont d’autres services ont besoin. Ce mode allie les avantages de la sécurité de niveau transport aux avantages présentés par la sécurité de niveau message, notamment celui d'utiliser un nombre illimité d'informations d'identification. Ceci est disponible avec les liaisons suivantes : BasicHttpBinding, , WSFederationHttpBindingNetPeerTcpBinding, et WSHttpBinding.
Si vous décidez d’utiliser la sécurité de transport pour HTTP (en d’autres termes, HTTPS), vous devez également configurer l’hôte avec un certificat SSL et activer SSL sur un port. Pour plus d’informations, consultez HTTP Transport Security.
Si vous utilisez la WSHttpBinding et que vous n’avez pas besoin d’établir une session sécurisée, définissez la propriété EstablishSecurityContext sur
false
.Une session sécurisée se produit lorsqu’un client et un service créent un canal à l’aide d’une clé symétrique (le client et le serveur utilisent la même clé pour la longueur d’une conversation, jusqu’à ce que la boîte de dialogue soit fermée).
Définition du type d’informations d’identification du client
Sélectionnez un type d’informations d’identification client selon les besoins. Pour plus d’informations, consultez Sélection d’un type d’informations d’identification. Les types d’informations d’identification client suivants sont disponibles :
Windows
Certificate
Digest
Basic
UserName
NTLM
IssuedToken
Selon la façon dont vous définissez le mode, vous devez définir le type d’informations d’identification. Par exemple, si vous avez sélectionné le wsHttpBinding
message et que vous avez défini le mode sur « Message », vous pouvez également définir l’attribut clientCredentialType
de l’élément Message sur l’une des valeurs suivantes : None
, , Windows
, UserName
Certificate
et IssuedToken
, comme illustré dans l’exemple de configuration suivant.
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="myBinding">
<security mode="Message"/>
<message clientCredentialType="Windows"/>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
Ou dans le code :
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
Définition des valeurs d'informations d'identification service
Une fois que vous avez sélectionné un type d’informations d’identification client, vous devez définir les informations d’identification réelles du service et du client à utiliser. Sur le service, les informations d’identification sont définies à l’aide de la ServiceCredentials classe et retournées par la Credentials propriété de la ServiceHostBase classe. Les types d'informations d'identification service et client ainsi que le mode de sécurité dépendent de la liaison utilisée. Le code suivant définit un certificat pour les informations d’identification d’un service.
// 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
Définition des valeurs d'informations d'identification client
Sur le client, définissez les valeurs d’informations d’identification du client en utilisant la classe ClientCredentials et retournées par la propriété ClientCredentials de la classe ClientBase<TChannel>. Le code suivant définit un certificat comme informations d’identification sur un client à l’aide du protocole 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()