Partilhar via


Federação

Este tópico fornece uma breve visão geral do conceito de segurança federada. Ele também descreve o suporte do Windows Communication Foundation (WCF) para implantar arquiteturas de segurança federadas. Para obter um aplicativo de exemplo que demonstra a federação, consulte Exemplo de federação.

Definição de Segurança Federada

A segurança federada permite uma separação clara entre o serviço que um cliente está acessando e os procedimentos de autenticação e autorização associados. A segurança federada também permite a colaboração entre vários sistemas, redes e organizações em diferentes reinos de confiança.

O WCF fornece suporte para criar e implantar sistemas distribuídos que empregam segurança federada.

Elementos de uma arquitetura de segurança federada

A arquitetura de segurança federada tem três elementos-chave, conforme descrito na tabela a seguir.

Elemento Description
Domínio/domínio Uma única unidade de administração de segurança ou confiança. Um domínio típico pode incluir uma única organização.
Federação Uma coleção de domínios que estabeleceram confiança. O nível de confiança pode variar, mas, normalmente, inclui autenticação e quase sempre inclui autorização. Uma federação típica pode incluir várias organizações que estabeleceram confiança para acesso compartilhado a um conjunto de recursos.
Serviço de Token de Segurança (STS) Um serviço Web que emite tokens de segurança; ou seja, faz afirmações com base em provas em que confia, em quem nela confia. Isso forma a base da intermediação de confiança entre domínios.

Cenário de Exemplo

A ilustração a seguir mostra um exemplo de segurança federada:

Diagram showing a typical federated security scenario.

Este cenário inclui duas organizações: A e B. A organização B tem um recurso Web (um serviço Web) que alguns utilizadores na organização A consideram valioso.

Nota

Esta seção usa os termos recurso, serviço e serviço Web de forma intercambiável.

Normalmente, a organização B exige que um usuário da organização A forneça alguma forma válida de autenticação antes de acessar o serviço. Além disso, a organização também pode exigir que o usuário seja autorizado a acessar o recurso específico em questão. Uma maneira de resolver esse problema e permitir que os usuários na organização A acessem o recurso na organização B é a seguinte:

  • Os usuários da organização A registram suas credenciais (um nome de usuário e senha) com a organização B.

  • Durante o acesso ao recurso, os usuários da organização A apresentam suas credenciais à organização B e são autenticados antes de acessar o recurso.

Esta abordagem apresenta três inconvenientes significativos:

  • A organização B tem que gerenciar as credenciais dos usuários da organização A, além de gerenciar as credenciais de seus usuários locais.

  • Os usuários na organização A precisam manter um conjunto adicional de credenciais (ou seja, lembrar um nome de usuário e senha adicionais) além das credenciais que normalmente usam para obter acesso a recursos dentro da organização A. Isso geralmente incentiva a prática de usar o mesmo nome de usuário e senha em vários sites de serviço, o que é uma medida de segurança fraca.

  • A arquitetura não é dimensionada à medida que mais organizações percebem o recurso na organização B como sendo de algum valor.

Uma abordagem alternativa, que aborda as desvantagens mencionadas anteriormente, é empregar segurança federada. Nessa abordagem, as organizações A e B estabelecem uma relação de confiança e empregam o Serviço de Token de Segurança (STS) para permitir a intermediação da confiança estabelecida.

Em uma arquitetura de segurança federada, os usuários da organização A sabem que, se quiserem acessar o serviço Web na organização B, devem apresentar um token de segurança válido do STS na organização B, que autentica e autoriza seu acesso ao serviço específico.

Ao entrar em contato com o STS B, os usuários recebem outro nível de indirecionamento da política associada ao STS. Eles devem apresentar um token de segurança válido do STS A (ou seja, o reino de confiança do cliente) antes que o STS B possa emitir um token de segurança. Este é um corolário da relação de confiança estabelecida entre as duas organizações e implica que a organização B não tem de gerir identidades para utilizadores da organização A. Na prática, o STS B normalmente tem um nulo issuerAddress e issuerMetadataAddress. Para obter mais informações, consulte Como configurar um emissor local. Nesse caso, o cliente consulta uma política local para localizar o STS A. Essa configuração é chamada de federação de realm doméstico e é melhor dimensionada porque o STS B não precisa manter informações sobre o STS A.

Em seguida, os usuários entram em contato com o STS na organização A e obtêm um token de segurança apresentando credenciais de autenticação que normalmente usam para obter acesso a qualquer outro recurso dentro da organização A. Isso também alivia o problema de os usuários terem que manter vários conjuntos de credenciais ou usar o mesmo conjunto de credenciais em vários sites de serviço.

Depois que os usuários obtêm um token de segurança do STS A, eles apresentam o token ao STS B. A organização B passa a executar a autorização das solicitações dos usuários e emite um token de segurança para os usuários a partir de seu próprio conjunto de tokens de segurança. Os usuários podem então apresentar seu token para o recurso na organização B e acessar o serviço.

Suporte para segurança federada no WCF

O WCF fornece suporte turnkey para implantar arquiteturas de segurança federadas por meio do wsFederationHttpBinding>.<

O <elemento wsFederationHttpBinding> fornece uma ligação segura, confiável e interoperável que implica o uso de HTTP como o mecanismo de transporte subjacente para o estilo de comunicação solicitação-resposta, empregando texto e XML como o formato de fio para codificação.

O uso de wsFederationHttpBinding> em um cenário de segurança federada pode ser dissociado <em duas fases logicamente independentes, conforme descrito nas seções a seguir.

Fase 1: Fase de projeto

Durante a fase de design, o cliente usa a ServiceModel Metadata Utility Tool (Svcutil.exe) para ler a política que o ponto de extremidade do serviço expõe e coletar os requisitos de autenticação e autorização do serviço. Os proxies apropriados são construídos para criar o seguinte padrão de comunicação de segurança federada no cliente:

  • Obtenha um token de segurança do STS na região de confiança do cliente.

  • Apresente o token ao STS no domínio de confiança do serviço.

  • Obtenha um token de segurança do STS na região de confiança do serviço.

  • Apresente o token ao serviço para acessar o serviço.

Fase 2: Fase de tempo de execução

Durante a fase de tempo de execução, o cliente instancia um objeto da classe de cliente WCF e faz uma chamada usando o cliente WCF. A estrutura subjacente do WCF lida com as etapas mencionadas anteriormente no padrão de comunicação de segurança federada e permite que o cliente consuma o serviço sem problemas.

Exemplo de implementação usando WCF

A ilustração a seguir mostra uma implementação de exemplo para uma arquitetura de segurança federada usando suporte nativo do WCF.

Diagram showing a sample Federation security implementation.

Exemplo MyService

O serviço MyService expõe um único ponto de extremidade através do MyServiceEndpoint. A ilustração a seguir mostra o endereço, a vinculação e o contrato associados ao ponto de extremidade.

Diagram showing the MyServiceEndpoint details.

O ponto de extremidade MyServiceEndpoint de serviço usa o <wsFederationHttpBinding> e requer um token SAML (Security Assertions Markup Language) válido com uma accessAuthorized declaração emitida pelo STS B. Isso é especificado declarativamente na configuração do serviço.

<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>  

Nota

Um ponto sutil deve ser observado sobre as reivindicações exigidas pela MyService. A segunda figura indica que MyService requer um token SAML com a accessAuthorized declaração. Para ser mais preciso, isso especifica o tipo de declaração que MyService requer. O nome totalmente qualificado desse tipo de declaração é http://tempuri.org:accessAuthorized (junto com o namespace associado), que é usado no arquivo de configuração do serviço. O valor desta declaração indica a presença desta declaração e presume-se que seja definido pelo true STS B.

Em tempo de execução, essa política é imposta pela classe que é implementada MyServiceOperationRequirement como parte do 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

A ilustração a seguir mostra o STS B. Como dito anteriormente, um serviço de token de segurança (STS) também é um serviço Web e pode ter seus pontos de extremidade associados, política e assim por diante.

Diagram showing security token service B.

O STS B expõe um único ponto de extremidade, chamado STSEndpoint que pode ser usado para solicitar tokens de segurança. Especificamente, o STS B emite tokens SAML com a accessAuthorized declaração, que pode ser apresentada no site do MyService serviço para acessar o serviço. No entanto, o STS B exige que os usuários apresentem um token SAML válido emitido pelo STS A que contenha a userAuthenticated declaração. Isso é especificado declarativamente na configuração do 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>  

Nota

Mais uma vez, a userAuthenticated declaração é o tipo de declaração exigido pelo STS B. O nome totalmente qualificado desse tipo de declaração é http://tempuri.org:userAuthenticated (junto com o namespace associado), que é usado no arquivo de configuração STS. O valor desta declaração indica a presença desta declaração e presume-se que seja definido pelo true STS A.

Em tempo de execução, a STS_B_OperationRequirement classe impõe essa política, que é implementada como parte do 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

Se a verificação de acesso estiver limpa, o STS B emitirá um token SAML com a accessAuthorized declaração.

// 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

A ilustração a seguir mostra o STS A.

Federation

Semelhante ao STS B, o STS A também é um serviço Web que emite tokens de segurança e expõe um único ponto de extremidade para essa finalidade. No entanto, ele usa uma ligação diferente (wsHttpBinding) e exige que os usuários apresentem um CardSpace válido com uma emailAddress reivindicação. Em resposta, ele emite tokens SAML com a userAuthenticated reivindicação. Isso é especificado declarativamente na configuração do serviço.

<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>  

Em tempo de execução, a STS_A_OperationRequirement classe impõe essa política, que é implementada como parte do 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

Se o acesso for true, o STS A emitirá um token SAML com userAuthenticated declaração.

// 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)

Cliente na Organização A

A ilustração a seguir mostra o cliente na organização A, juntamente com as etapas envolvidas na realização de uma MyService chamada de serviço. Os outros componentes funcionais também estão incluídos para completude.

Diagram showing the steps in a MyService service call.

Resumo

A segurança federada fornece uma divisão limpa de responsabilidades e ajuda a criar arquiteturas de serviço seguras e escaláveis. Como uma plataforma para criar e implantar aplicativos distribuídos, o WCF fornece suporte nativo para a implementação de segurança federada.

Consulte também