Partager via


Fédération

Cette rubrique fournit une brève vue d’ensemble du concept de sécurité fédérée. Il décrit également la prise en charge de Windows Communication Foundation (WCF) pour le déploiement d’architectures de sécurité fédérées. Pour obtenir un exemple d’application qui illustre la fédération, consultez l’exemple de fédération.

Définition de la sécurité fédérée

La sécurité fédérée permet une séparation propre entre le service auquel un client accède et les procédures d’authentification et d’autorisation associées. La sécurité fédérée permet également la collaboration entre plusieurs systèmes, réseaux et organisations dans différents domaines de confiance.

WCF prend en charge la création et le déploiement de systèmes distribués qui utilisent la sécurité fédérée.

Éléments d’une architecture de sécurité fédérée

L’architecture de sécurité fédérée comporte trois éléments clés, comme décrit dans le tableau suivant.

Élément Descriptif
Domaine/sphère Une unité unique d'administration de sécurité ou de confiance. Un domaine classique peut inclure une seule organisation.
Fédération Une collection de domaines qui ont établi une confiance. Le niveau de confiance peut varier, mais inclut généralement l’authentification et presque toujours l’autorisation. Une fédération classique peut inclure un certain nombre d’organisations qui ont établi une approbation pour l’accès partagé à un ensemble de ressources.
Service d’émission de jeton de sécurité (STS) Service Web qui émet des jetons de sécurité ; c’est-à-dire qu’elle fait des assertions basées sur des preuves qu’elle approuve, à quiconque en fait confiance. C'est la base de la gestion de la confiance entre domaines.

Exemple de scénario

L’illustration suivante montre un exemple de sécurité fédérée :

Diagramme montrant un scénario de sécurité fédéré classique.

Ce scénario comprend deux organisations : A et B. Organization B a une ressource Web (un service Web) que certains utilisateurs de l’organisation A trouvent précieuses.

Remarque

Cette section utilise les termes de la ressource, du service et du service Web de manière interchangeable.

En règle générale, l’organisation B exige qu’un utilisateur de l’organisation A fournisse une forme d’authentification valide avant d’accéder au service. En outre, l’organisation peut également exiger que l’utilisateur soit autorisé à accéder à la ressource spécifique en question. L’une des façons de résoudre ce problème et d’autoriser les utilisateurs de l’organisation A à accéder à la ressource dans l’organisation B est la suivante :

  • Les utilisateurs de l’organisation A inscrivent leurs informations d’identification (un nom d’utilisateur et un mot de passe) auprès de l’organisation B.

  • Pendant l’accès aux ressources, les utilisateurs de l’organisation A présentent leurs informations d’identification à l’organisation B et sont authentifiés avant d’accéder à la ressource.

Cette approche présente trois inconvénients importants :

  • L’organisation B doit gérer les informations d’identification des utilisateurs de l’organisation A en plus de gérer les informations d’identification de ses utilisateurs locaux.

  • Les utilisateurs de l’organisation A doivent conserver un ensemble supplémentaire d’informations d’identification (autrement dit, n’oubliez pas un nom d’utilisateur et un mot de passe supplémentaires) en dehors des informations d’identification qu’ils utilisent normalement pour accéder aux ressources au sein de l’organisation A. Cela encourage généralement la pratique d’utiliser le même nom d’utilisateur et le même mot de passe sur plusieurs sites de service, ce qui est une mesure de sécurité faible.

  • L’architecture n’est pas mise à l’échelle, car davantage d’organisations perçoivent la ressource au niveau de l’organisation B comme étant d’une valeur quelconque.

Une autre approche, qui traite des inconvénients mentionnés précédemment, consiste à utiliser la sécurité fédérée. Dans cette approche, les organisations A et B établissent une relation de confiance et utilisent le Security Token Service (STS) pour permettre la gestion de la confiance établie.

Dans une architecture de sécurité fédérée, les utilisateurs de l’organisation A savent que s’ils veulent accéder au service Web dans l’organisation B, ils doivent présenter un jeton de sécurité valide à partir du STS au niveau de l’organisation B, qui authentifie et autorise leur accès au service spécifique.

En contactant le STS B, les utilisateurs reçoivent un autre niveau d’indirection lié à la politique associée au STS. Ils doivent présenter un jeton de sécurité valide en provenance du STS A (autrement dit, le domaine d’approbation du client) avant que le STS B puisse leur émettre un jeton de sécurité. Il s’agit d’une conséquence de la relation d’approbation établie entre les deux organisations et implique que l’organisation B n’ait pas à gérer les identités des utilisateurs de l’organisation A. Dans la pratique, STS B a généralement une valeur null issuerAddress et issuerMetadataAddress. Pour plus d’informations, consultez Guide pratique pour configurer un émetteur local. Dans ce cas, le client consulte une stratégie locale pour localiser STS A. Cette configuration est appelée fédération de domaine d’accueil et elle s’adapte mieux, car STS B n’a pas besoin de conserver des informations sur STS A.

Les utilisateurs contactent ensuite le STS au niveau de l’organisation A et obtiennent un jeton de sécurité en présentant les informations d’identification d’authentification qu’ils utilisent normalement pour accéder à toute autre ressource au sein de l’organisation A. Cela réduit également le problème des utilisateurs qui doivent gérer plusieurs ensembles d’informations d’identification ou utiliser le même ensemble d’informations d’identification sur plusieurs sites de service.

Une fois que les utilisateurs ont obtenu un jeton de sécurité à partir du STS A, ils présentent le jeton à l’organisation STS B. L’organisation B procède à l’autorisation des demandes des utilisateurs et émet un jeton de sécurité aux utilisateurs à partir de son propre ensemble de jetons de sécurité. Les utilisateurs peuvent ensuite présenter leur jeton à la ressource à l’organisation B et accéder au service.

Prise en charge de la sécurité fédérée dans WCF

WCF fournit une prise en charge clé en main du déploiement d’architectures de sécurité fédérées via <wsFederationHttpBinding>.

L’élément <wsFederationHttpBinding> fournit une liaison sécurisée, fiable et interopérable qui implique l’utilisation du protocole HTTP comme mécanisme de transport sous-jacent pour le style de communication de requête-réponse, en utilisant du texte et du code XML comme format filaire pour l’encodage.

L’utilisation de <wsFederationHttpBinding> dans un scénario de sécurité fédéré peut être découplée en deux phases indépendantes logiquement, comme décrit dans les sections suivantes.

Phase 1 : Phase de conception

Pendant la phase de conception, le client utilise l’outil Utilitaire de métadonnées ServiceModel (Svcutil.exe) pour lire la stratégie que le point de terminaison de service expose et pour collecter les exigences d’authentification et d’autorisation du service. Les proxys appropriés sont construits pour créer le modèle de communication de sécurité fédéré suivant au niveau du client :

  • Procurez-vous un jeton de sécurité auprès du STS du domaine de confiance du client.

  • Présentez le jeton au STS du domaine de confiance du service.

  • Procurez-vous un jeton de sécurité auprès du STS du domaine de confiance du service.

  • Présenter le jeton au service pour accéder au service.

Phase 2 : phase d'exécution

Pendant la phase d’exécution, le client instancie un objet de la classe cliente WCF et effectue un appel à l’aide du client WCF. L’infrastructure sous-jacente de WCF gère les étapes mentionnées précédemment dans le modèle de communication de sécurité fédérée et permet au client de consommer en toute transparence le service.

Exemple d’implémentation à l’aide de WCF

L’illustration suivante montre un exemple d’implémentation pour une architecture de sécurité fédérée à l’aide de la prise en charge native de WCF.

Diagramme montrant un exemple d’implémentation de sécurité de fédération.

Exemple de MyService

Le service MyService expose un point de terminaison unique via MyServiceEndpoint. L'illustration suivante présente l'adresse, la liaison et le contrat associés au point de terminaison.

Diagramme montrant les détails de MyServiceEndpoint.

Le point de terminaison MyServiceEndpoint de service utilise wsFederationHttpBinding<> et nécessite un jeton SAML (Security Assertions Markup Language) valide avec une accessAuthorized revendication émise par STS B. Cela est spécifié de manière déclarative dans la configuration du service.

<system.serviceModel>
  <services>
    <service type="FederationSample.MyService"
        behaviorConfiguration='MyServiceBehavior'>
        <endpoint address=""
            binding=" wsFederationHttpBinding"
            bindingConfiguration='MyServiceBinding'
            contract="Federation.IMyService" />
   </service>
  </services>

  <bindings>
    <wsFederationHttpBinding>
    <!-- This is the binding used by MyService. It redirects
    clients to STS-B. -->
      <binding name='MyServiceBinding'>
        <security mode="Message">
           <message issuedTokenType=
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
           <issuer address="http://localhost/FederationSample/STS-B/STS.svc" />
            <issuerMetadata
           address=
"http://localhost/FederationSample/STS-B/STS.svc/mex" />
         <requiredClaimTypes>
            <add claimType="http://tempuri.org:accessAuthorized" />
         </requiredClaimTypes>
        </message>
      </security>
      </binding>
    </wsFederationHttpBinding>
  </bindings>

  <behaviors>
    <behavior name='MyServiceBehavior'>
      <serviceAuthorization
operationRequirementType="FederationSample.MyServiceOperationRequirement, MyService" />
       <serviceCredentials>
         <serviceCertificate findValue="CN=FederationSample.com"
         x509FindType="FindBySubjectDistinguishedName"
         storeLocation='LocalMachine'
         storeName='My' />
      </serviceCredentials>
    </behavior>
  </behaviors>
</system.serviceModel>

Remarque

Un point subtil mérite d'être souligné concernant les réclamations requises par MyService. La deuxième figure indique que MyService nécessite un jeton SAML avec la accessAuthorized revendication. Pour être plus précis, cela spécifie le type de revendication requis MyService . Le nom complet de ce type de revendication est http://tempuri.org:accessAuthorized (ainsi que l’espace de noms associé), qui est utilisé dans le fichier de configuration du service. La valeur de cette revendication indique la présence de cette revendication et est supposée être définie true par STS B.

Au moment de l’exécution, cette stratégie est appliquée par la classe MyServiceOperationRequirement, qui est implémentée dans le cadre de MyService.

using System.Collections.Generic;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel;
Imports System.Collections.Generic
Imports System.IdentityModel.Claims
Imports System.IdentityModel.Policy
Imports System.IdentityModel.Tokens
Imports System.Security.Cryptography.X509Certificates
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Security.Tokens
Imports System.Text
public class myServiceAuthorizationManager : ServiceAuthorizationManager
{
    // Override the CheckAccess method to enforce access control requirements.
    public override bool CheckAccess(OperationContext operationContext)
    {
        AuthorizationContext authContext =
        operationContext.ServiceSecurityContext.AuthorizationContext;
        if (authContext.ClaimSets == null) return false;
        if (authContext.ClaimSets.Count != 1) return false;
        ClaimSet myClaimSet = authContext.ClaimSets[0];
        if (!IssuedBySTS_B(myClaimSet)) return false;
        if (myClaimSet.Count != 1) return false;
        Claim myClaim = myClaimSet[0];
        if (myClaim.ClaimType ==
          "http://www.tmpuri.org:accessAuthorized")
        {
            string resource = myClaim.Resource as string;
            if (resource == null) return false;
            if (resource != "true") return false;
            return true;
        }
        else
        {
            return false;
        }
    }

    // This helper method checks whether SAML Token was issued by STS-B.
    // It compares the Thumbprint Claim of the Issuer against the
    // Certificate of STS-B.
    private bool IssuedBySTS_B(ClaimSet myClaimSet)
    {
        ClaimSet issuerClaimSet = myClaimSet.Issuer;
        if (issuerClaimSet == null) return false;
        if (issuerClaimSet.Count != 1) return false;
        Claim issuerClaim = issuerClaimSet[0];
        if (issuerClaim.ClaimType != ClaimTypes.Thumbprint)
            return false;
        if (issuerClaim.Resource == null) return false;
        byte[] claimThumbprint = (byte[])issuerClaim.Resource;
        // It is assumed that stsB_Certificate is a variable of type
        // X509Certificate2 that is initialized with the Certificate of
        // STS-B.
        X509Certificate2 stsB_Certificate = GetStsBCertificate();
        byte[] certThumbprint = stsB_Certificate.GetCertHash();
        if (claimThumbprint.Length != certThumbprint.Length)
            return false;
        for (int i = 0; i < claimThumbprint.Length; i++)
        {
            if (claimThumbprint[i] != certThumbprint[i]) return false;
        }
        return true;
    }
Public Class myServiceAuthorizationManager
    Inherits ServiceAuthorizationManager

    ' Override the CheckAccess method to enforce access control requirements.
    Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
        Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
        If authContext.ClaimSets Is Nothing Then
            Return False
        End If

        If authContext.ClaimSets.Count <> 1 Then
            Return False
        End If

        Dim myClaimSet = authContext.ClaimSets(0)
        If Not IssuedBySTS_B(myClaimSet) Then
            Return False
        End If
        If myClaimSet.Count <> 1 Then
            Return False
        End If
        Dim myClaim = myClaimSet(0)
        If myClaim.ClaimType = "http://www.tmpuri.org:accessAuthorized" Then
            Dim resource = TryCast(myClaim.Resource, String)
            If resource Is Nothing Then
                Return False
            End If
            If resource <> "true" Then
                Return False
            End If
            Return True
        Else
            Return False
        End If
    End Function

    ' This helper method checks whether SAML Token was issued by STS-B.     
    ' It compares the Thumbprint Claim of the Issuer against the 
    ' Certificate of STS-B. 
    Private Function IssuedBySTS_B(ByVal myClaimSet As ClaimSet) As Boolean
        Dim issuerClaimSet = myClaimSet.Issuer
        If issuerClaimSet Is Nothing Then
            Return False
        End If
        If issuerClaimSet.Count <> 1 Then
            Return False
        End If
        Dim issuerClaim = issuerClaimSet(0)
        If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
            Return False
        End If
        If issuerClaim.Resource Is Nothing Then
            Return False
        End If
        Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
        ' It is assumed that stsB_Certificate is a variable of type 
        ' X509Certificate2 that is initialized with the Certificate of 
        ' STS-B.
        Dim stsB_Certificate = GetStsBCertificate()
        Dim certThumbprint() = stsB_Certificate.GetCertHash()
        If claimThumbprint.Length <> certThumbprint.Length Then
            Return False
        End If
        For i = 0 To claimThumbprint.Length - 1
            If claimThumbprint(i) <> certThumbprint(i) Then
                Return False
            End If
        Next i
        Return True
    End Function

STS B

L’illustration suivante montre le STS B. Comme indiqué précédemment, un service de jeton de sécurité (STS) est également un service Web et peut avoir ses points de terminaison, stratégie, et ainsi de suite.

Diagramme montrant le service de jeton de sécurité B.

STS B expose un point de terminaison unique, appelé STSEndpoint qui peut être utilisé pour demander des jetons de sécurité. Spécifiquement, STS B émet des jetons SAML avec l'assertion accessAuthorized, qui peuvent être présentés sur le site du service MyService pour accéder au service. Toutefois, STS B exige que les utilisateurs présentent un jeton SAML valide émis par STS A qui contient la userAuthenticated revendication. Il s’agit d’une spécification déclarative dans la configuration STS.

<system.serviceModel>
  <services>
    <service type="FederationSample.STS_B" behaviorConfiguration=
     "STS-B_Behavior">
    <endpoint address=""
              binding="wsFederationHttpBinding"
              bindingConfiguration='STS-B_Binding'
      contract="FederationSample.ISts" />
    </service>
  </services>
  <bindings>
    <wsFederationHttpBinding>
    <!-- This is the binding used by STS-B. It redirects clients to
         STS-A. -->
      <binding name='STS-B_Binding'>
        <security mode='Message'>
          <message issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
          <issuer address='http://localhost/FederationSample/STS-A/STS.svc' />
          <issuerMetadata address='http://localhost/FederationSample/STS-A/STS.svc/mex'/>
          <requiredClaimTypes>
            <add claimType='http://tempuri.org:userAuthenticated'/>
          </requiredClaimTypes>
          </message>
        </security>
    </binding>
   </wsFederationHttpBinding>
  </bindings>
  <behaviors>
  <behavior name='STS-B_Behavior'>
    <serviceAuthorization   operationRequirementType='FederationSample.STS_B_OperationRequirement, STS_B' />
    <serviceCredentials>
      <serviceCertificate findValue='CN=FederationSample.com'
      x509FindType='FindBySubjectDistinguishedName'
       storeLocation='LocalMachine'
       storeName='My' />
     </serviceCredentials>
   </behavior>
  </behaviors>
</system.serviceModel>

Remarque

Là encore, la userAuthenticated revendication est le type de revendication requis par STS B. Le nom complet de ce type de revendication est http://tempuri.org:userAuthenticated (ainsi que l’espace de noms associé), qui est utilisé dans le fichier de configuration STS. La valeur de cette revendication indique la présence de cette revendication et est supposée être définie true par STS A.

Au moment de l’exécution, la STS_B_OperationRequirement classe applique cette stratégie, qui est implémentée dans le cadre de STS B.

public class STS_B_AuthorizationManager : ServiceAuthorizationManager
{

    // Override AccessCheck to enforce access control requirements.
    public override bool CheckAccess(OperationContext operationContext)
    {
        AuthorizationContext authContext =
        operationContext.ServiceSecurityContext.AuthorizationContext;
        if (authContext.ClaimSets == null) return false;
        if (authContext.ClaimSets.Count != 1) return false;
        ClaimSet myClaimSet = authContext.ClaimSets[0];
        if (!IssuedBySTS_A(myClaimSet)) return false;
        if (myClaimSet.Count != 1) return false;
        Claim myClaim = myClaimSet[0];
        if (myClaim.ClaimType == "http://www.tmpuri.org:userAuthenticated")
        {
            string resource = myClaim.Resource as string;
            if (resource == null) return false;
            if (resource != "true") return false;
            return true;
        }
        else
        {
            return false;
        }
    }

    // This helper method checks whether SAML Token was issued by STS-A.
    // It compares the Thumbprint Claim of the Issuer against the
    // Certificate of STS-A.
    private bool IssuedBySTS_A(ClaimSet myClaimSet)
    {
        ClaimSet issuerClaimSet = myClaimSet.Issuer;
        if (issuerClaimSet == null) return false;
        if (issuerClaimSet.Count != 1) return false;
        Claim issuerClaim = issuerClaimSet[0];
        if (issuerClaim.ClaimType != ClaimTypes.Thumbprint) return false;
        if (issuerClaim.Resource == null) return false;
        byte[] claimThumbprint = (byte[])issuerClaim.Resource;
        // It is assumed that stsA_Certificate is a variable of type X509Certificate2
        // that is initialized with the Certificate of STS-A.
        X509Certificate2 stsA_Certificate = GetStsACertificate();

        byte[] certThumbprint = stsA_Certificate.GetCertHash();
        if (claimThumbprint.Length != certThumbprint.Length) return false;
        for (int i = 0; i < claimThumbprint.Length; i++)
        {
            if (claimThumbprint[i] != certThumbprint[i]) return false;
        }
        return true;
    }
Public Class STS_B_AuthorizationManager
    Inherits ServiceAuthorizationManager

    ' Override AccessCheck to enforce access control requirements.
    Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
        Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
        If authContext.ClaimSets Is Nothing Then
            Return False
        End If
        If authContext.ClaimSets.Count <> 1 Then
            Return False
        End If
        Dim myClaimSet = authContext.ClaimSets(0)
        If Not IssuedBySTS_A(myClaimSet) Then
            Return False
        End If
        If myClaimSet.Count <> 1 Then
            Return False
        End If
        Dim myClaim = myClaimSet(0)
        If myClaim.ClaimType = "http://www.tmpuri.org:userAuthenticated" Then
            Dim resource = TryCast(myClaim.Resource, String)
            If resource Is Nothing Then
                Return False
            End If
            If resource <> "true" Then
                Return False
            End If
            Return True
        Else
            Return False
        End If
    End Function

    ' This helper method checks whether SAML Token was issued by STS-A. 
    ' It compares the Thumbprint Claim of the Issuer against the 
    ' Certificate of STS-A.
    Private Function IssuedBySTS_A(ByVal myClaimSet As ClaimSet) As Boolean
        Dim issuerClaimSet = myClaimSet.Issuer
        If issuerClaimSet Is Nothing Then
            Return False
        End If
        If issuerClaimSet.Count <> 1 Then
            Return False
        End If
        Dim issuerClaim = issuerClaimSet(0)
        If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
            Return False
        End If
        If issuerClaim.Resource Is Nothing Then
            Return False
        End If
        Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
        ' It is assumed that stsA_Certificate is a variable of type X509Certificate2
        ' that is initialized with the Certificate of STS-A.
        Dim stsA_Certificate = GetStsACertificate()

        Dim certThumbprint() = stsA_Certificate.GetCertHash()
        If claimThumbprint.Length <> certThumbprint.Length Then
            Return False
        End If
        For i = 0 To claimThumbprint.Length - 1
            If claimThumbprint(i) <> certThumbprint(i) Then
                Return False
            End If
        Next i
        Return True
    End Function

Si la vérification d'accès est validée, STS B émet un jeton SAML avec une revendication accessAuthorized.

// Create the list of SAML Attributes.
List<SamlAttribute> samlAttributes = new List<SamlAttribute>();

// Add the accessAuthorized claim.
List<string> strList = new List<string>();
strList.Add("true");
samlAttributes.Add(new SamlAttribute("http://www.tmpuri.org",
"accessAuthorized",
strList));

// Create the SAML token with the accessAuthorized claim. It is assumed that
// the method CreateSamlToken() is implemented as part of STS-B.
SamlSecurityToken samlToken = CreateSamlToken(
    proofToken,
    issuerToken,
    samlConditions,
    samlSubjectNameFormat,
    samlSubjectEmailAddress,
    samlAttributes);
' Create the list of SAML Attributes.
Dim samlAttributes As New List(Of SamlAttribute)()

' Add the accessAuthorized claim.
Dim strList As New List(Of String)()
strList.Add("true")
samlAttributes.Add(New SamlAttribute("http://www.tmpuri.org", "accessAuthorized", strList))

' Create the SAML token with the accessAuthorized claim. It is assumed that 
' the method CreateSamlToken() is implemented as part of STS-B.
Dim samlToken = CreateSamlToken(proofToken, _
                                issuerToken, _
                                samlConditions, _
                                samlSubjectNameFormat, _
                                samlSubjectEmailAddress, _
                                samlAttributes)

STS A

L’illustration suivante montre le STS A.

Fédération

À l’instar de STS B, le STS A est également un service Web qui émet des jetons de sécurité et expose un point de terminaison unique à cet effet. Toutefois, il utilise une autre liaison (wsHttpBinding) et exige que les utilisateurs présentent un CardSpace valide avec une assertion emailAddress. En réponse, il émet des jetons SAML avec la revendication userAuthenticated. Cela est spécifié de manière déclarative dans la configuration du service.

<system.serviceModel>
  <services>
    <service type="FederationSample.STS_A" behaviorConfiguration="STS-A_Behavior">
      <endpoint address=""
                binding="wsHttpBinding"
                bindingConfiguration="STS-A_Binding"
                contract="FederationSample.ISts">
       <identity>
       <certificateReference findValue="CN=FederationSample.com"
                       x509FindType="FindBySubjectDistinguishedName"
                       storeLocation="LocalMachine"
                       storeName="My" />
       </identity>
    </endpoint>
  </service>
</services>

<bindings>
  <wsHttpBinding>
  <!-- This is the binding used by STS-A. It requires users to present
   a CardSpace. -->
    <binding name='STS-A_Binding'>
      <security mode='Message'>
        <message clientCredentialType="CardSpace" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<behaviors>
  <behavior name='STS-A_Behavior'>
    <serviceAuthorization operationRequirementType=
     "FederationSample.STS_A_OperationRequirement, STS_A" />
      <serviceCredentials>
  <serviceCertificate findValue="CN=FederationSample.com"
                     x509FindType='FindBySubjectDistinguishedName'
                     storeLocation='LocalMachine'
                     storeName='My' />
      </serviceCredentials>
    </behavior>
  </behaviors>
</system.serviceModel>

Au moment de l’exécution, la STS_A_OperationRequirement classe applique cette stratégie, qui est implémentée dans le cadre de STS A.


public class STS_A_AuthorizationManager : ServiceAuthorizationManager
{
    // Override AccessCheck to enforce access control requirements.
    public override bool CheckAccess(OperationContext operationContext)
    {
        AuthorizationContext authContext =
        operationContext.ServiceSecurityContext.AuthorizationContext;
        if (authContext.ClaimSets == null) return false;
        if (authContext.ClaimSets.Count != 1) return false;
        ClaimSet myClaimSet = authContext.ClaimSets[0];
        if (myClaimSet.Count != 1) return false;
        Claim myClaim = myClaimSet[0];
        if ((myClaim.ClaimType ==
        @"http://schemas.microsoft.com/ws/2005/05/identity/claims:EmailAddress") &&
        (myClaim.Right == Rights.PossessProperty))
        {
            string emailAddress = myClaim.Resource as string;
            if (emailAddress == null) return false;
            if (!IsValidEmailAddress(emailAddress)) return false;
            return true;
        }
        else
        {
            return false;
        }
    }

    // This helper method performs a rudimentary check for whether
    //a given email is valid.
    private static bool IsValidEmailAddress(string emailAddress)
    {
        string[] splitEmail = emailAddress.Split('@');
        if (splitEmail.Length != 2) return false;
        if (!splitEmail[1].Contains(".")) return false;
        return true;
    }
}
Public Class STS_A_AuthorizationManager
    Inherits ServiceAuthorizationManager

    ' Override AccessCheck to enforce access control requirements.
    Public Overloads Overrides Function CheckAccess(ByVal operationContext As OperationContext) As Boolean
        Dim authContext = operationContext.ServiceSecurityContext.AuthorizationContext
        If authContext.ClaimSets Is Nothing Then
            Return False
        End If
        If authContext.ClaimSets.Count <> 1 Then
            Return False
        End If
        Dim myClaimSet = authContext.ClaimSets(0)
        If myClaimSet.Count <> 1 Then
            Return False
        End If
        Dim myClaim = myClaimSet(0)
        If myClaim.ClaimType = "http://schemas.microsoft.com/ws/2005/05/identity/claims:EmailAddress" AndAlso myClaim.Right = Rights.PossessProperty Then
            Dim emailAddress = TryCast(myClaim.Resource, String)
            If emailAddress Is Nothing Then
                Return False
            End If
            If Not IsValidEmailAddress(emailAddress) Then
                Return False
            End If
            Return True
        Else
            Return False
        End If
    End Function

    ' This helper method performs a rudimentary check for whether 
    'a given email is valid.
    Private Shared Function IsValidEmailAddress(ByVal emailAddress As String) As Boolean
        Dim splitEmail() = emailAddress.Split("@"c)
        If splitEmail.Length <> 2 Then
            Return False
        End If
        If Not splitEmail(1).Contains(".") Then
            Return False
        End If
        Return True
    End Function
End Class

Si l'accès est true, le STS A émet un jeton SAML avec la revendication userAuthenticated.

// Create the list of SAML Attributes.
List<SamlAttribute> samlAttributes = new List<SamlAttribute>();
// Add the userAuthenticated claim.
List<string> strList = new List<string>();
strList.Add("true");
SamlAttribute mySamlAttribute = new SamlAttribute("http://www.tmpuri.org",
     "userAuthenticated", strList);
samlAttributes.Add(mySamlAttribute);
// Create the SAML token with the userAuthenticated claim. It is assumed that
// the method CreateSamlToken() is implemented as part of STS-A.
SamlSecurityToken samlToken = CreateSamlToken(
    proofToken,
    issuerToken,
    samlConditions,
    samlSubjectNameFormat,
    samlSubjectEmailAddress,
    samlAttributes);
' Create the list of SAML Attributes.
Dim samlAttributes As New List(Of SamlAttribute)()
' Add the userAuthenticated claim.
Dim strList As New List(Of String)()
strList.Add("true")
Dim mySamlAttribute As New SamlAttribute("http://www.tmpuri.org", _
                                         "userAuthenticated", _
                                         strList)
samlAttributes.Add(mySamlAttribute)
' Create the SAML token with the userAuthenticated claim. It is assumed that 
' the method CreateSamlToken() is implemented as part of STS-A.
Dim samlToken = CreateSamlToken(proofToken, issuerToken, samlConditions, _
                                samlSubjectNameFormat, _
                                samlSubjectEmailAddress, _
                                samlAttributes)

Client au niveau de l’organisation A

L’illustration suivante montre le client de l’organisation A, ainsi que les étapes impliquées dans la réalisation d’un MyService appel de service. Les autres composants fonctionnels sont également inclus pour l’exhaustivité.

Diagramme montrant les étapes d’un appel de service MyService.

Résumé

La sécurité fédérée offre une division propre de responsabilité et permet de créer des architectures de service sécurisées et évolutives. En tant que plateforme pour la création et le déploiement d’applications distribuées, WCF fournit une prise en charge native de l’implémentation de la sécurité fédérée.

Voir aussi