Remarque
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 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 :
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.
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.
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.
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.
À 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é.
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.