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.
L’emprunt d’identité est une technique courante que les services utilisent pour restreindre l’accès client aux ressources d’un domaine de service. Les ressources de domaine de service peuvent être des ressources d'ordinateur, telles que des fichiers locaux (emprunt d'identité), ou une ressource sur un autre ordinateur, tel qu'un partage de fichiers (délégation). Pour un exemple d'application, consultez Usurper l'identité du client. Pour obtenir un exemple d’utilisation de l’usurpation d’identité, consultez Comment usurper l’identité d’un client sur un service.
Importante
N’oubliez pas que lors de l’emprunt d’identité d’un client sur un service, le service s’exécute avec les informations d’identification du client, qui peuvent avoir des privilèges plus élevés que le processus serveur.
Aperçu
En règle générale, les clients appellent un service pour que le service effectue une action au nom du client. L’emprunt d’identité permet au service d’agir en tant que client lors de l’exécution de l’action. La délégation permet à un service frontal de transférer la requête du client vers un service back-end de manière à ce que le service back-end puisse également usurper l'identité du client. L’emprunt d’identité est le plus couramment utilisé pour vérifier si un client est autorisé à effectuer une action particulière, tandis que la délégation est un moyen de transmettre les fonctionnalités d’emprunt d’identité, ainsi que l’identité du client, à un service principal. La délégation est une fonctionnalité de domaine Windows qui peut être utilisée lorsque l’authentification Kerberos est effectuée. La délégation est distincte du flux d’identité et, étant donné que la délégation transfère la possibilité d’emprunter l’identité du client sans possession du mot de passe du client, il s’agit d’une opération privilégiée beaucoup plus élevée que le flux d’identité.
L’emprunt d’identité et la délégation nécessitent que le client dispose d’une identité Windows. Si un client ne possède pas d’identité Windows, la seule option disponible consiste à transmettre l’identité du client au deuxième service.
Principes fondamentaux de l'usurpation d'identité
Windows Communication Foundation (WCF) prend en charge l'usurpation d'identité pour divers identifiants client. Cette rubrique décrit la prise en charge de modèle de service permettant d'emprunter l'identité de l'appelant pendant l'implémentation d'une méthode de service. Les scénarios de déploiement courants impliquant l’emprunt d’identité et la sécurité SOAP et les options WCF sont également abordés dans ces scénarios.
Cette rubrique se concentre sur l’emprunt d’identité et la délégation dans WCF lors de l’utilisation de la sécurité SOAP. Vous pouvez également utiliser l’emprunt d’identité et la délégation avec WCF lors de l’utilisation de la sécurité de transport, tel que décrit dans Utilisation de l’emprunt d’identité avec la sécurité de transport.
Deux méthodes
La sécurité SOAP WCF a deux méthodes distinctes pour l’exécution de l’emprunt d’identité. La méthode utilisée dépend du type de reliure. L'une concerne l'emprunt d'identité à partir d'un jeton Windows fourni par l'authentification SSPI (Security Support Provider Interface) ou Kerberos, qui est ensuite mis en cache sur le service. La deuxième concerne l'emprunt d'identité à partir d'un jeton Windows fourni par les extensions Kerberos, collectivement appelées S4U (Service-for-User).
Emprunt d'identité avec jeton mis en cache
Vous pouvez effectuer l'emprunt d'identité avec jeton mis en cache à l'aide des éléments suivants :
WSHttpBinding, WSDualHttpBindinget NetTcpBinding avec des informations d’identification client Windows.
BasicHttpBinding avec un BasicHttpSecurityMode configuré pour l’identifiant TransportWithMessageCredential, ou toute autre liaison standard où le client présente des informations d'identification de nom d'utilisateur que le service peut associer à un compte Windows valide.
Tout CustomBinding qui utilise une information d'identification de client Windows avec
requireCancellation
défini àtrue
. (La propriété est disponible sur les classes suivantes : SecureConversationSecurityTokenParameters, SslSecurityTokenParameters, et SspiSecurityTokenParameters.) Si une conversation sécurisée est utilisée sur la liaison, elle doit également avoir la propriétérequireCancellation
définie surtrue
.Tout CustomBinding où le client présente une authentification par nom d'utilisateur. Si une conversation sécurisée est utilisée sur la liaison, sa propriété
requireCancellation
doit également avoir la valeurtrue
.
Emprunt d'identité basé sur S4U
Vous pouvez effectuer l'emprunt d'identité basé sur S4U à l'aide des éléments suivants :
WSHttpBinding, WSDualHttpBinding et NetTcpBinding avec une information d'identification de client de certificat que le service peut mapper à un compte Windows valide.
Tout CustomBinding qui utilise une information d'identification de client Windows avec la propriété
requireCancellation
définie àfalse
.Tout CustomBinding qui utilise un nom d'utilisateur ou une information d'identification de client Windows et une conversation sécurisée avec la propriété
requireCancellation
définie àfalse
.
La mesure dans laquelle le service peut emprunter l’identité du client dépend des privilèges que le compte de service conserve lorsqu’il tente d’emprunter l’identité, le type d’emprunt d’identité utilisé et éventuellement l’étendue de l’emprunt d’identité que le client autorise.
Remarque
Lorsque le client et le service s'exécutent sur le même ordinateur et que le client s'exécute sous un compte système (par exemple, Local System
ou Network Service
), il n'est pas possible d'emprunter l'identité du client lorsqu'une session sécurisée est établie avec les jetons de contexte de sécurité avec état. Une application Windows Form ou console s’exécute généralement sous le compte actuellement connecté, afin que ce compte puisse être usurpé par défaut. Toutefois, lorsque le client est une page ASP.NET et que cette page est hébergée dans IIS 6.0 ou IIS 7.0, le client s’exécute sous le Network Service
compte par défaut. Toutes les liaisons fournies par le système qui prennent en charge des sessions sécurisées utilisent par défaut un jeton de contexte de sécurité sans état. Toutefois, si le client est une page ASP.NET, et que des sessions sécurisées avec jetons de contexte de sécurité (SCT) avec état sont utilisées, l’emprunt de l’identité du client est impossible. Pour plus d’informations sur l’utilisation de scT avec état dans une session sécurisée, consultez Guide pratique pour créer un jeton de contexte de sécurité pour une session sécurisée.
Emprunt d'identité dans une méthode de service : modèle déclaratif
La plupart des scénarios d’usurpation d’identité impliquent l’exécution de la méthode de service dans le contexte de l’appelant. WCF fournit une fonctionnalité d’emprunt d’identité qui facilite cette opération en permettant à l’utilisateur de spécifier l’exigence d’emprunt d’identité dans l’attribut OperationBehaviorAttribute . Par exemple, dans le code suivant, l’infrastructure WCF usurpe l’identité de l’appelant avant d’exécuter la méthode Hello
. Toute tentative d’accès aux ressources natives à l’intérieur de la Hello
méthode réussit uniquement si la liste de contrôle d’accès (ACL) de la ressource autorise les privilèges d’accès de l’appelant. Pour activer l'emprunt d'identité, affectez l'une des valeurs d'énumération Impersonation ( ImpersonationOption ou ImpersonationOption.Required ) à la propriété ImpersonationOption.Allowed, tel qu'indiqué dans l'exemple suivant.
Remarque
Lorsqu’un service a des informations d’identification supérieures à celles du client distant, les informations d’identification du service sont utilisées si la propriété Impersonation est définie sur Allowed. Autrement dit, si un utilisateur à privilèges faibles fournit ses informations d’identification, un service à privilèges supérieurs exécute la méthode avec les informations d’identification du service et peut utiliser des ressources que l’utilisateur à privilèges faibles ne serait pas en mesure d’utiliser.
[ServiceContract]
public interface IHelloContract
{
[OperationContract]
string Hello(string message);
}
public class HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Hello(string message)
{
return "hello";
}
}
<ServiceContract()> _
Public Interface IHelloContract
<OperationContract()> _
Function Hello(ByVal message As String) As String
End Interface
Public Class HelloService
Implements IHelloService
<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
Return "hello"
End Function
End Class
L’infrastructure WCF peut emprunter l’identité de l’appelant uniquement si l’appelant est authentifié avec des informations d’identification qui peuvent être mappées à un compte d’utilisateur Windows. Si le service est configuré pour s’authentifier à l’aide d’informations d’identification qui ne peuvent pas être mappées à un compte Windows, la méthode de service n’est pas exécutée.
Remarque
Sur Windows XP, l’emprunt d’identité échoue si un jeton de contexte de sécurité (SCT) avec état est créé, ce qui génère un InvalidOperationException. Pour plus d’informations, consultez Scénarios non pris en charge.
Usurpation d'identité dans une méthode de service : modèle impératif
Un appelant n'a parfois pas besoin d'emprunter l'identité de l'ensemble de la méthode de service pour fonctionner, mais uniquement une partie de celle-ci. Dans ce cas, obtenez l'identité Windows de l'appelant à l'intérieur de la méthode de service et exécutez l'emprunt d'identité de manière impérative. Pour ce faire, utilisez la WindowsIdentity propriété de la ServiceSecurityContext propriété pour retourner une instance de la WindowsIdentity classe et appeler la Impersonate méthode avant d’utiliser l’instance.
Remarque
Assurez-vous d’utiliser l’instruction Using
en Visual Basic ou l’instruction using
en C# pour rétablir automatiquement l’action d’emprunt d’identité. Si vous n’utilisez pas l’instruction, ou si vous utilisez un langage de programmation autre que Visual Basic ou C#, veillez à ramener le niveau d'usurpation d'identité à son état initial. L’échec de cette opération peut constituer la base d’attaques par déni de service et d’élévation de privilèges.
public class HelloService : IHelloService
{
[OperationBehavior]
public string Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a WindowsIdentity");
}
using (callerWindowsIdentity.Impersonate())
{
// Access a file as the caller.
}
return "Hello";
}
}
Public Class HelloService
Implements IHelloService
<OperationBehavior()> _
Public Function Hello(ByVal message As String) As String _
Implements IHelloService.Hello
Dim callerWindowsIdentity As WindowsIdentity = _
ServiceSecurityContext.Current.WindowsIdentity
If (callerWindowsIdentity Is Nothing) Then
Throw New InvalidOperationException( _
"The caller cannot be mapped to a WindowsIdentity")
End If
Dim cxt As WindowsImpersonationContext = callerWindowsIdentity.Impersonate()
Using (cxt)
' Access a file as the caller.
End Using
Return "Hello"
End Function
End Class
Emprunt d'identité pour toutes les méthodes de service
Dans certains cas, vous devez effectuer toutes les méthodes d’un service dans le contexte de l’appelant. Au lieu d’activer explicitement cette fonctionnalité par méthode, utilisez le ServiceAuthorizationBehavior. Comme indiqué dans le code suivant, définissez la ImpersonateCallerForAllOperations propriété sur true
. Le ServiceAuthorizationBehavior est récupéré à partir des collections de comportements de la classe ServiceHost. Notez également que la propriété Impersonation
de OperationBehaviorAttribute appliquée à chaque méthode doit également être définie sur Allowed ou Required.
// Code to create a ServiceHost not shown.
ServiceAuthorizationBehavior MyServiceAuthorizationBehavior =
serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = true;
' Code to create a ServiceHost not shown.
Dim MyServiceAuthorizationBehavior As ServiceAuthorizationBehavior
MyServiceAuthorizationBehavior = serviceHost.Description.Behaviors.Find _
(Of ServiceAuthorizationBehavior)()
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = True
Le tableau suivant décrit le comportement WCF pour toutes les combinaisons possibles de ImpersonationOption
et ImpersonateCallerForAllServiceOperations
.
ImpersonationOption |
ImpersonateCallerForAllServiceOperations |
Comportement |
---|---|---|
Obligatoire | n/a | Le WCF usurpe l'identité de l'appelant |
Autorisé | faux | WCF n’usurpe pas l’identité de l’appelant |
Autorisé | vrai | Le WCF usurpe l'identité de l'appelant |
Non autorisé | faux | WCF n’usurpe pas l’identité de l’appelant |
Non autorisé | vrai | Rejeté. (Une exception InvalidOperationException est levée.) |
Niveau d'emprunt d'identité obtenu à partir des informations d'identification Windows et emprunt d'identité avec jeton mis en cache
Dans certains scénarios, le client a un contrôle partiel sur le niveau d’emprunt d’identité que le service effectue lorsqu’une information d’identification du client Windows est utilisée. Un scénario se produit lorsque le client spécifie un niveau d’imitation anonyme. L'autre se produit lors de l'exécution de l'emprunt d'identité avec un jeton mis en cache. Pour ce faire, définissez la AllowedImpersonationLevel propriété de la WindowsClientCredential classe, accessible en tant que propriété de la classe générique ChannelFactory<TChannel> .
Remarque
Si vous spécifiez un niveau d’emprunt d’identité d’Anonymous, le client se connecte au service de façon anonyme. Le service doit donc autoriser des ouvertures de session anonymes, indépendamment de l'exécution de l'emprunt d'identité.
Le client peut spécifier le niveau d’emprunt d’identité comme Anonymous, Identification, Impersonation ou Delegation. Seul un jeton au niveau spécifié est produit, comme indiqué dans le code suivant.
ChannelFactory<IEcho> cf = new ChannelFactory<IEcho>("EchoEndpoint");
cf.Credentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
Dim cf As ChannelFactory(Of IEcho) = New ChannelFactory(Of IEcho)("EchoEndpoint")
cf.Credentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Impersonation
Le tableau suivant spécifie le niveau d'emprunt d'identité que le service obtient lors de l'emprunt d'identité à partir d'un jeton mis en cache.
valeur AllowedImpersonationLevel |
Le Service a SeImpersonatePrivilege |
Le service et le client peuvent être délégués | Jeton mis en cache ImpersonationLevel |
---|---|---|---|
Anonyme | Oui | n/a | Usurpation d'identité |
Anonyme | Non | n/a | Identification |
Identification | n/a | n/a | Identification |
Usurpation d'identité | Oui | n/a | Usurpation d'identité |
Usurpation d'identité | Non | n/a | Identification |
Délégation | Oui | Oui | Délégation |
Délégation | Oui | Non | Usurpation d'identité |
Délégation | Non | n/a | Identification |
Niveau d'emprunt d'identité obtenu à partir des informations d'identification de nom d'utilisateur et emprunt d'identité avec jeton mis en cache
En transmettant son nom d’utilisateur et son mot de passe au service, un client permet à WCF de se connecter en tant que cet utilisateur, ce qui équivaut à définir la propriété AllowedImpersonationLevel
Delegation. (Le AllowedImpersonationLevel
est disponible dans les classes WindowsClientCredential et HttpDigestClientCredential.) Le tableau suivant fournit le niveau de simulation d'identité obtenu lorsque le service reçoit les informations d'identification du nom d'utilisateur.
AllowedImpersonationLevel |
Le Service a SeImpersonatePrivilege |
Le service et le client peuvent être délégués | Jeton mis en cache ImpersonationLevel |
---|---|---|---|
n/a | Oui | Oui | Délégation |
n/a | Oui | Non | Usurpation d'identité |
n/a | Non | n/a | Identification |
Niveau d'emprunt d'identité obtenu à partir de l'emprunt d'identité basé sur S4U
Le Service a SeTcbPrivilege |
Le Service a SeImpersonatePrivilege |
Le service et le client peuvent être délégués | Jeton mis en cache ImpersonationLevel |
---|---|---|---|
Oui | Oui | n/a | Usurpation d'identité |
Oui | Non | n/a | Identification |
Non | n/a | n/a | Identification |
Mappage d’un certificat client à un compte Windows
Il est possible qu’un client s’authentifie auprès d’un service à l’aide d’un certificat et que le service mappe le client à un compte existant via Active Directory. Le code XML suivant montre comment configurer le service pour mapper le certificat.
<behaviors>
<serviceBehaviors>
<behavior name="MapToWindowsAccount">
<serviceCredentials>
<clientCertificate>
<authentication mapClientCertificateToWindowsAccount="true" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Le code suivant montre comment configurer le service.
// Create a binding that sets a certificate as the client credential type.
WSHttpBinding b = new WSHttpBinding();
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
// Create a service host that maps the certificate to a Windows account.
Uri httpUri = new Uri("http://localhost/Calculator");
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;
Délégation
Pour déléguer à un service back-end, un service doit effectuer une authentification Kerberos multi-étape (SSPI sans recours à NTLM) ou une authentification directe Kerberos vers le service back-end à l’aide de l’identité Windows du client. Pour déléguer à un service back-end, créez un ChannelFactory<TChannel> et un canal, puis communiquez via le canal en se faisant passer pour le client. Avec cette forme de délégation, la distance entre l'emplacement du service principal et le service frontal dépend du niveau d'emprunt d'identité atteint par le service frontal. Lorsque le niveau d'emprunt d'identité est Impersonation, les services frontaux et principaux doivent s'exécuter sur le même ordinateur. Lorsque le niveau d'emprunt d'identité est Delegation, les services frontaux et principaux peuvent être présents sur des ordinateurs séparés ou sur le même ordinateur. L’activation de l’emprunt d’identité au niveau de la délégation nécessite que la stratégie de domaine Windows soit configurée pour autoriser la délégation. Pour plus d’informations sur la configuration d’Active Directory pour la prise en charge de la délégation, consultez Activation de l’authentification déléguée.
Remarque
Lorsqu’un client s’authentifie auprès du service frontal à l’aide d’un nom d’utilisateur et d’un mot de passe correspondant à un compte Windows sur le service principal, le service frontal peut s’authentifier auprès du service principal en réutilisant le nom d’utilisateur et le mot de passe du client. Il s’agit d’une forme particulièrement puissante de flux d’identité, car le passage du nom d’utilisateur et du mot de passe au service principal permet au service principal d’effectuer l’emprunt d’identité, mais il ne constitue pas une délégation, car Kerberos n’est pas utilisé. Les contrôles Active Directory sur la délégation ne s’appliquent pas à l’authentification par nom d’utilisateur et mot de passe.
Capacité de délégation en tant que fonction du niveau d’usurpation d’identité
Niveau d'emprunt d'identité | Le service peut effectuer une délégation inter-processus | Le service peut effectuer une délégation sur plusieurs ordinateurs |
---|---|---|
Identification | Non | Non |
Impersonation | Oui | Non |
Delegation | Oui | Oui |
L’exemple de code suivant montre comment utiliser la délégation.
public class HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Hello(string message)
{
WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
throw new InvalidOperationException
("The caller cannot be mapped to a Windows identity.");
}
using (callerWindowsIdentity.Impersonate())
{
EndpointAddress backendServiceAddress = new EndpointAddress("http://localhost:8000/ChannelApp");
// Any binding that performs Windows authentication of the client can be used.
ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>(new NetTcpBinding(), backendServiceAddress);
IHelloService channel = channelFactory.CreateChannel();
return channel.Hello(message);
}
}
}
Public Class HelloService
Implements IHelloService
<OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
Dim callerWindowsIdentity As WindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity
If (callerWindowsIdentity Is Nothing) Then
Throw New InvalidOperationException("The caller cannot be mapped to a Windows identity.")
End If
Dim backendServiceAddress As EndpointAddress = New EndpointAddress("http://localhost:8000/ChannelApp")
' Any binding that performs Windows authentication of the client can be used.
Dim channelFactory As ChannelFactory(Of IHelloService) = _
New ChannelFactory(Of IHelloService)(New NetTcpBinding(), backendServiceAddress)
Dim channel As IHelloService = channelFactory.CreateChannel()
Return channel.Hello(message)
End Function
End Class
Comment configurer une application pour utiliser la délégation contrainte
Avant de pouvoir utiliser la délégation contrainte, l’expéditeur, le destinataire et le contrôleur de domaine doivent être configurés pour le faire. La procédure suivante répertorie les étapes qui activent la délégation contrainte. Pour plus d’informations sur les différences entre la délégation et la délégation contrainte, consultez la partie des extensions Kerberos Windows Server 2003 qui traite de la discussion contrainte.
Sur le contrôleur de domaine, désactivez la case à cocher « Compte est sensible et ne peut pas être délégué » pour le compte sous lequel l'application cliente s'exécute.
Sur le contrôleur de domaine, activez la case à cocher Compte approuvé pour la délégation pour le compte sous lequel l’application cliente s’exécute.
Sur le contrôleur de domaine, configurez l’ordinateur de niveau intermédiaire afin qu’il soit approuvé pour la délégation, en cliquant sur l’option Approuver l’ordinateur pour la délégation .
Sur le contrôleur de domaine, configurez l’ordinateur de niveau intermédiaire pour qu’il utilise la délégation contrainte, en cliquant sur l’option Approuver cet ordinateur pour la délégation aux services spécifiés uniquement .
Pour obtenir des instructions plus détaillées sur la configuration de la délégation contrainte, consultez Transition de protocole Kerberos et Délégation contrainte.
Voir aussi
- OperationBehaviorAttribute
- Impersonation
- ImpersonationOption
- WindowsIdentity
- ServiceSecurityContext
- WindowsIdentity
- ServiceAuthorizationBehavior
- ImpersonateCallerForAllOperations
- ServiceHost
- AllowedImpersonationLevel
- WindowsClientCredential
- ChannelFactory<TChannel>
- Identification
- Utilisation de l'emprunt d'identité avec la sécurité de transport
- Usurpation d'identité du client
- Procédure : emprunter l’identité d’un client sur un service
- Outil utilitaire de métadonnées ServiceModel (Svcutil.exe)