Fédération
Cette rubrique fournit une brève vue d'ensemble du concept de sécurité fédérée. Elle décrit également le support de Windows Communication Foundation (WCF) pour le déploiement d’architectures de sécurité fédérées. Pour un exemple d’application présentant la fédération, consultez Federation, exemple.
Définition de sécurité fédérée
La sécurité fédérée permet une séparation nette 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 sur plusieurs systèmes, réseaux et organisations dans les différents domaines de confiance.
WCF prend en charge la génération et le déploiement de systèmes distribués qui utilisent une 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 a trois éléments clés, tel qu'indiqué dans le tableau suivant.
Élément | Description |
---|---|
Domaine | Unité unique de confiance ou d'administration de sécurité. Un domaine classique peut inclure une organisation unique. |
Fédération | Collection de domaines qui ont établi la confiance. Le niveau de confiance peut varier, mais il inclut généralement l’authentification et presque toujours l’autorisation. Une fédération classique peut inclure plusieurs organisations qui ont établi une confiance pour un accès partagé à un ensemble de ressources. |
Service d'émission de jeton de sécurité (STS, Security Token Service) | Service Web qui émet des jetons de sécurité ; autrement dit, fait des assertions en fonction de la preuve qu'il approuve, à quiconque l'approuve. Il constitue la base de l'échange de confiance entre les domaines. |
Exemple de scénario
L’illustration suivante présente un exemple de sécurité fédérée :
Ce scénario inclut deux organisations : A et B. L'organisation B a une ressource Web (un service Web) que certains utilisateurs de l'organisation A trouvent utile.
Notes
Cette section utilise les termes ressource, service et service web de manière interchangeable.
En général, l'organisation B requiert qu'un utilisateur de l'organisation A fournisse des formulaires d'authentification valides avant d'accéder au service. De plus, l'organisation peut également requérir que l'utilisateur soit autorisé à accéder à la ressource spécifique en question. L'une des méthodes pour résoudre ce problème et permettre aux utilisateurs de l'organisation A d'accéder à la ressource de l'organisation B est la suivante :
Les utilisateurs de l'organisation A enregistrent leurs informations d'identification (nom d'utilisateur et 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 a trois inconvénients significatifs :
L'organisation B doit gérer les informations d'identification des utilisateurs de l'organisation A, outre la gestion de ses utilisateurs internes.
Les utilisateurs de l'organisation A doivent gérer un ensemble d'informations d'identification supplémentaire (autrement dit, se souvenir d'un nom d'utilisateur et d'un mot de passe supplémentaires) outre les informations d'identification qu'ils utilisent habituellement pour accéder aux ressources dans l'organisation A. Cela favorise la pratique qui consiste à utiliser des noms d'utilisateur et mots de passe identiques au niveau de plusieurs sites de service, ce qui est une mesure de sécurité faible.
L'architecture n'évolue pas car plusieurs organisations perçoivent la ressource de l'organisation B comme étant utile.
L'autre approche, qui résout les inconvénients précédemment mentionnés, 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 STS pour permettre l'échange de la confiance établie.
Dans une architecture de sécurité fédérée, les utilisateurs de l'organisation A savent que s'ils souhaitent accéder au service Web de l'organisation B, ils doivent présenter un jeton de sécurité valide provenant du STS à l'organisation B, qui authentifie et autorise leur accès au service spécifique.
Lorsqu'ils contactent le STS B, les utilisateurs reçoivent un autre niveau d'indirection de la stratégie associée au STS. Ils doivent présenter un jeton de sécurité valide provenant du STS A (autrement dit, le domaine de confiance client) pour que le STS B puisse leur délivrer un jeton de sécurité. C'est un corollaire de la relation de confiance établie entre les deux organisations et cela implique que l'organisation B n'a pas à gérer des identités pour les utilisateurs de l'organisation A. Dans la pratique, le STS B a en général un issuerAddress
et un issuerMetadataAddress
null. Pour plus d’informations, consultez Comment : Configurer un émetteur local. Dans ce cas, le client consulte une stratégie locale pour localiser le STS A. Cette configuration est appelée fédération de domaines et facilite la mise à l’échelle car le STS B n’a pas à gérer d’informations sur le STS A.
Les utilisateurs contactent ensuite le STS de l'organisation A et obtiennent un jeton de sécurité en présentant les informations d'identification qu'ils utilisent habituellement pour accéder aux autres ressources de l'organisation A. Cela évite aux utilisateurs d'avoir à gérer plusieurs ensembles d'informations d'identification ou à utiliser le même ensemble au niveau de plusieurs sites de service.
Une fois que les utilisateurs obtiennent un jeton de sécurité du STS A, ils présentent le jeton au STS B. L'organisation B continue à procéder à l'autorisation des demandes des utilisateurs et leur envoie un jeton de sécurité provenant de son propre jeu. Les utilisateurs peuvent ensuite présenter leur jeton à la ressource de l'organisation B et accéder au service.
Prise en charge de la sécurité fédérée dans WCF
WCF fournit la prise en charge clé en main permettant de déployer des architectures de sécurité fédérée via l’élément <wsFederationHttpBinding>.
L’élément <wsFederationHttpBinding> fournit une liaison sécurisée, fiable, interopérable qui implique l’utilisation de HTTP comme mécanisme de transport sous-jacent pour le type de communication demande-réponse, en utilisant le format texte et XML comme format de câble pour l’encodage.
L’utilisation de <wsFederationHttpBinding> dans un scénario de sécurité fédérée peut être divisée en deux phases logiquement indépendantes, comme décrit dans les sections suivantes.
Phase 1 : phase de conception
Pendant la phase de conception, le client utilise l’outil Service Model Metadata Utility (Svcutil.exe) pour lire la stratégie exposée par le point de terminaison de service et collecter les spécifications 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ée 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ésentez 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 de client WCF et lance un appel à l’aide du client WCF. L’infrastructure sous-jacente de WCF gère les étapes précédemment mentionnées dans le modèle de communication de sécurité fédérée et active le client pour consommer le service de façon transparente.
Exemple d'implémentation à l'aide de WCF
L’illustration suivante présente un exemple d’implémentation pour une architecture de sécurité fédérée utilisant la prise en charge native de WCF.
Exemple 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 de service MyServiceEndpoint
utilise <wsFederationHttpBinding> et requiert un jeton SAML (Security Assertions Markup Language) avec une revendication accessAuthorized
émise par le STS B. Cela est spécifié de façon déclarative dans la configuration de 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>
Notes
Un point subtil doit être noté concernant les revendications requises par MyService
. La deuxième figure indique que MyService
requiert un jeton SAML avec la revendication accessAuthorized
. Pour être plus précis, cela spécifie le type de revendication que MyService
requiert. Le nom complet de ce type de revendication est http://tempuri.org:accessAuthorized
(avec l’espace de noms associé), qui est utilisé dans le fichier de configuration de service. La valeur de cette revendication indique sa présence et elle est supposée être définie à true
par le STS B.
Pendant l’exécution, cette stratégie est appliquée par la classe MyServiceOperationRequirement
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 présente le STS B. Comme indiqué précédemment, un service d'émission de jeton de sécurité (STS) est également un service Web et peut avoir ses points de terminaison associés, sa stratégie, etc.
STS B expose un point de terminaison unique appelé STSEndpoint
qui permet de demander des jetons de sécurité. Plus précisément, le STS B émet des jetons SAML avec la revendication accessAuthorized
, qui peuvent être présentés au niveau du site de service MyService
permettant d'accéder au service. Toutefois, le STS B requiert que les utilisateurs présentent un jeton SAML valide émis par le STS A qui contient la revendication userAuthenticated
. Cela est spécifié de façon déclarative dans la configuration de 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>
Notes
Une nouvelle fois, la revendication userAuthenticated
est le type de revendication requis par le STS B. Le nom complet de ce type de revendication est http://tempuri.org:userAuthenticated
(avec l’espace de noms associé), qui est utilisé dans le fichier de configuration de STS. La valeur de cette revendication indique sa présence et elle est supposée être définie à true
par le STS A.
Pendant l’exécution, la classe STS_B_OperationRequirement
applique cette stratégie, qui est implémentée dans le cadre du 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 le contrôle d'accès est clair, le STS B émet un jeton SAML avec la 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 présente le STS A.
À l'instar du STS B, le STS A est également un service Web qui émet des jetons de sécurité et expose un point de terminaison unique à cette fin. Toutefois, il utilise une liaison différente (wsHttpBinding
) et requiert que les utilisateurs présentent un CardSpace valide avec une revendication emailAddress
. En réponse, il émet des jetons SAML avec la revendication userAuthenticated
. Cela est spécifié de façon déclarative dans la configuration de 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>
Pendant l’exécution, la classe STS_A_OperationRequirement
applique cette stratégie, qui est implémentée dans le cadre du STS B.
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 présente le client au niveau de l'organisation A, ainsi que les étapes impliquées dans le lancement d'un appel de service MyService
. Les autres composants fonctionnels sont également inclus par souci d'exhaustivité.
Résumé
La sécurité fédérée fournit une division nette de la responsabilité et permet de générer des architectures de service sécurisées et évolutives. À l’instar d’une plateforme de génération et de déploiement d’applications distribuées, WCF fournit une prise en charge native permettant d’implémenter la sécurité fédérée.