Como: criar um cliente federado

No Windows Communication Foundation (WCF), a criação de um cliente para um serviço federado consiste em três etapas principais:

  1. Configure um <wsFederationHttpBinding> ou uma associação personalizada semelhante. Para obter mais informações sobre como criar uma associação apropriada, consulte Como criar WSFederationHttpBinding. Como alternativa, execute a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe) no ponto de extremidade de metadados do serviço federado para gerar um arquivo de configuração que se comunica com o serviço federado e um ou mais serviços de token de segurança.

  2. Defina as propriedades de IssuedTokenClientCredential que controla vários aspectos da interação de um cliente com um serviço de token de segurança.

  3. Defina as propriedades de X509CertificateRecipientClientCredential que permite os certificados exigidos se comunicarem com segurança com determinados pontos de extremidade, como serviços de token de segurança.

Observação

Um CryptographicException pode ser gerado quando um cliente usa credenciais representadas, associação WSFederationHttpBinding ou um token personalizado emitido e chaves assimétricas. As chaves assimétricas são usadas com a associação WSFederationHttpBinding e os tokens personalizados emitidos quando as propriedades IssuedKeyType e KeyType, respectivamente, são definidas como AsymmetricKey. CryptographicException é gerado quando o cliente tenta enviar uma mensagem e um perfil de usuário não existe para a identidade que o cliente representa. Para reduzir esse problema, faça logon no computador cliente ou chame LoadUserProfile antes de enviar a mensagem.

Este tópico apresenta informações detalhadas sobre esses procedimentos. Para obter mais informações sobre como criar uma associação apropriada, consulte Como criar WSFederationHttpBinding. Para obter mais informações sobre como funciona um serviço federado, consulte Federação.

Para gerar e examinar a configuração de um serviço federado

  1. Execute a Ferramenta do Utilitário de Metadados do ServiceModel (Svcutil.exe) com o endereço da URL de metadados do serviço como um parâmetro de linha de comando.

  2. Abra o arquivo de configuração gerado em um editor apropriado.

  3. Analise os atributos e o conteúdo de qualquer <emissor> gerado e elementos <issuerMetadata>. Eles estão localizados dentro dos elementos de <segurança> para os elementos <wsFederationHttpBinding> ou elementos de associações personalizadas. Verifique se os endereços contêm os nomes de domínio esperados ou outras informações de endereço. É importante verificar essas informações porque o cliente faz a autenticação nesses endereços e pode divulgar informações como pares de nome de usuário/senha. Se o endereço não for o endereço previsto, pode resultar na divulgação de informações para um destinatário não intencional.

  4. Analise quaisquer elementos adicionais <issuedTokenParameters> dentro do elemento comentado <alternativeIssuedTokenParameters>. Ao usar a ferramenta Svcutil.exe para gerar a configuração para um serviço federado, e o serviço federado ou qualquer serviço de token de segurança intermediário não especificar um endereço de emissor, mas especificar um endereço de metadados para um serviço de token de segurança que mostra vários pontos de extremidade, o arquivo de configuração resultante se refere ao primeiro ponto de extremidade. Pontos de extremidade adicionais estão no arquivo de configuração como elementos comentados <alternativeIssuedTokenParameters>.

    Determine se um deles <issuedTokenParameters> tem preferência ao que já está presente na configuração. Por exemplo, o cliente pode preferir autenticar um serviço de token de segurança usando um token do Windows CardSpace em vez de nome de usuário/senha.

    Observação

    Quando vários serviços de token de segurança são percorridos antes de se comunicar com o serviço, é possível que um serviço de token de segurança intermediário direcione o cliente a um serviço de token de segurança incorreto. Portanto, verifique se o ponto de extremidade do serviço de token de segurança no <issuedTokenParameters> é o serviço de token de segurança previsto e não um serviço de token de segurança desconhecido.

Para configurar um IssuedTokenClientCredential no código

  1. Acesse IssuedTokenClientCredential pela propriedade IssuedToken da classe ClientCredentials (retornada pela propriedade ClientCredentials da classe ClientBase<TChannel> ou pela classe ChannelFactory), conforme mostrado no código de exemplo a seguir.

    IssuedTokenClientCredential itcc = client.ClientCredentials.IssuedToken;
    
    Dim itcc As IssuedTokenClientCredential = client.ClientCredentials.IssuedToken
    
  2. Se não for necessário o cache de token, defina a propriedade CacheIssuedTokens como false. A propriedade CacheIssuedTokens controla se esses tokens de um serviço de token de segurança são armazenados em cache. Se essa propriedade for definida como false, o cliente solicita um novo token do serviço de token de segurança sempre que precisar se autenticar novamente no serviço federado, independentemente de um token anterior ainda ter validade. Se essa propriedade for definida como true, o cliente reutiliza um token existente sempre que precisar se autenticar novamente no serviço federado (desde que o token não tenha expirado). O padrão é true.

  3. Se for necessário um limite de tempo em tokens armazenados em cache, defina a propriedade MaxIssuedTokenCachingTime como um valor TimeSpan. A propriedade especifica quanto tempo um token pode ser armazenado em cache. Depois de ter decorrido o intervalo de tempo especificado, o token será removido do cache do cliente. Por padrão, os tokens são armazenados em cache de forma indefinida. O exemplo a seguir define o intervalo de tempo como 10 minutos.

    itcc.MaxIssuedTokenCachingTime = new TimeSpan(0, 10, 0);
    
    itcc.MaxIssuedTokenCachingTime = New TimeSpan(0, 10, 0)
    
  4. Opcional. Defina IssuedTokenRenewalThresholdPercentage como uma porcentagem. O padrão é 60 (por cento). A propriedade especifica uma porcentagem do período de validade do token. Por exemplo, se o token emitido for válido por 10 horas e IssuedTokenRenewalThresholdPercentage for definido como 80, o token será renovado após oito horas. O exemplo a seguir define o valor como 80%.

    itcc.IssuedTokenRenewalThresholdPercentage = 80;
    
    itcc.IssuedTokenRenewalThresholdPercentage = 80
    

    O intervalo de renovação determinado pelo período de validade do token e o valor IssuedTokenRenewalThresholdPercentage é substituído pelo valor MaxIssuedTokenCachingTime em casos em que o tempo de cache é menor que o tempo de limite de renovação. Por exemplo, se o produto de IssuedTokenRenewalThresholdPercentage e a duração do token for de oito horas e o valor MaxIssuedTokenCachingTime for de 10 minutos, o cliente entra em contato com o serviço de token de segurança para obter um token atualizado a cada 10 minutos.

  5. Se um modo de entropia de chave diferente de CombinedEntropy for necessário em uma associação que não usa segurança de mensagem ou segurança de transporte com credenciais de mensagem (por exemplo, a associação não tem um SecurityBindingElement), defina a propriedade DefaultKeyEntropyMode como um valor apropriado. O modo entropia determina se as chaves simétricas podem ser controladas usando a propriedade DefaultKeyEntropyMode. Esse padrão é CombinedEntropy, em que o cliente e o emissor do token fornecem dados combinados para produzir a chave real. Outros valores são ClientEntropy e ServerEntropy, o que significa que toda a chave é especificada pelo cliente ou pelo servidor, respectivamente. O exemplo a seguir define a propriedade para usar apenas os dados do servidor para a chave.

    itcc.DefaultKeyEntropyMode = SecurityKeyEntropyMode.ServerEntropy;
    
    itcc.DefaultKeyEntropyMode = SecurityKeyEntropyMode.ServerEntropy
    

    Observação

    Se estiver SecurityBindingElement presente em um serviço de token de segurança ou associação de serviço, o conjunto DefaultKeyEntropyMode em IssuedTokenClientCredential será substituído pela propriedade KeyEntropyMode do SecurityBindingElement.

  6. Configure qualquer comportamento de ponto de extremidade específico do emissor adicionando-os à coleção retornada pela propriedade IssuerChannelBehaviors.

    itcc.LocalIssuerChannelBehaviors.Add(myEndpointBehavior);
    
    itcc.LocalIssuerChannelBehaviors.Add(myEndpointBehavior)
    

Para configurar o IssuedTokenClientCredential na configuração

  1. Crie um elemento <issuedToken> como um filho do elemento <issuedToken> em um comportamento de ponto de extremidade.

  2. Se o cache de token não for necessário, defina o atributo cacheIssuedTokens (do elemento <issuedToken>) como false.

  3. Se for necessário um limite de tempo em tokens armazenados em cache, defina o atributo maxIssuedTokenCachingTime no elemento <issuedToken> como um valor apropriado. Por exemplo:
    <issuedToken maxIssuedTokenCachingTime='00:10:00' />

  4. Se for preferível um valor diferente do padrão, defina o atributo issuedTokenRenewalThresholdPercentage no elemento <issuedToken> como um valor apropriado, por exemplo:

    <issuedToken issuedTokenRenewalThresholdPercentage = "80" />  
    
  5. Se um modo de entropia de chave diferente de CombinedEntropy estiver em uma associação que não usa segurança de mensagem ou segurança de transporte com credenciais de mensagem (por exemplo, a associação não tem um SecurityBindingElement), defina o atributo defaultKeyEntropyMode no elemento <issuedToken> como ServerEntropy ou ClientEntropy conforme exigido.

    <issuedToken defaultKeyEntropyMode = "ServerEntropy" />  
    
  6. Opcional. Configure qualquer comportamento de ponto de extremidade personalizado específico do emissor criando um elemento <issuerChannelBehaviors> como filho do elemento <issuedToken>. Para cada comportamento, crie um elemento <add> como um filho do elemento <issuerChannelBehaviors>. Especifique o endereço do emissor do comportamento definindo o atributo issuerAddress no elemento <add>. Especifique o próprio comportamento definindo o atributo behaviorConfiguration no elemento <add>.

    <issuerChannelBehaviors>  
    <add issuerAddress="http://fabrikam.org/sts" behaviorConfiguration="FabrikamSTS" />  
    </issuerChannelBehaviors>  
    

Para configurar um X509CertificateRecipientClientCredential no código

  1. Acesse X509CertificateRecipientClientCredential por meio da propriedade ServiceCertificate da propriedade ClientCredentials da classe ClientBase<TChannel> ou da propriedade ChannelFactory.

    X509CertificateRecipientClientCredential rcc =
        client.ClientCredentials.ServiceCertificate;
    
    Dim rcc As X509CertificateRecipientClientCredential = _
    client.ClientCredentials.ServiceCertificate
    
  2. Se uma instância X509Certificate2 estiver disponível para o certificado de um determinado ponto de extremidade, use o método Add da coleção retornada pela propriedade ScopedCertificates.

    rcc.ScopedCertificates.Add(new Uri("http://fabrikam.com/sts"), cert);
    
    rcc.ScopedCertificates.Add(New Uri("http://fabrikam.com/sts"), cert)
    
  3. Se uma instância X509Certificate2 não estiver disponível, use o método SetScopedCertificate da classe X509CertificateRecipientClientCredential, conforme mostrado no exemplo a seguir.

    public void snippet20(CalculatorClient client)
    {
        X509CertificateRecipientClientCredential rcc = client.ClientCredentials.ServiceCertificate;
        rcc.SetScopedCertificate(StoreLocation.CurrentUser,
                                 StoreName.TrustedPeople,
                                 X509FindType.FindBySubjectName,
                                 "FabrikamSTS",
                                 new Uri("http://fabrikam.com/sts"));
    }
    
    rcc.SetScopedCertificate(StoreLocation.CurrentUser, _
                StoreName.TrustedPeople, _
                X509FindType.FindBySubjectName, _
                "FabrikamSTS", _
                New Uri("http://fabrikam.com/sts"))
    

Para configurar um X509CertificateRecipientClientCredential na configuração

  1. Crie um elemento <scopedCertificates> como um filho do elemento <serviceCertificate> que é próprio de um filho do elemento <clientCredentials> em um comportamento de ponto de extremidade.

  2. Crie um elemento <add> como um filho do elemento <scopedCertificates>. Especifique valores para os atributos storeLocation, storeName, x509FindType e findValue para fazer referência ao certificado apropriado. Defina o atributo targetUri como um valor que fornece o endereço do ponto de extremidade para o qual o certificado deve ser usado, conforme mostrado no exemplo a seguir.

    <scopedCertificates>  
     <add targetUri="http://fabrikam.com/sts"
          storeLocation="CurrentUser"  
          storeName="TrustedPeople"  
          x509FindType="FindBySubjectName"  
          findValue="FabrikamSTS" />  
    </scopedCertificates>  
    

Exemplo

O exemplo de código a seguir configura uma instância da classe IssuedTokenClientCredential no código.

// This method configures the IssuedToken property of the Credentials property of a proxy/channel factory
public static void ConfigureIssuedTokenClientCredentials(ChannelFactory cf, bool cacheTokens,
                                                          TimeSpan tokenCacheTime, int renewalPercentage,
                                                          SecurityKeyEntropyMode entropyMode
                                                          )
{
    if (cf == null)
    {
        throw new ArgumentNullException("cf");
    }
    // Set the CacheIssuedTokens property
    cf.Credentials.IssuedToken.CacheIssuedTokens = cacheTokens;

    // Set the MaxIssuedTokenCachingTime property
    cf.Credentials.IssuedToken.MaxIssuedTokenCachingTime = tokenCacheTime;

    // Set the IssuedTokenRenewalThresholdPercentage property
    cf.Credentials.IssuedToken.IssuedTokenRenewalThresholdPercentage = renewalPercentage;

    // Set the DefaultKeyEntropyMode property
    cf.Credentials.IssuedToken.DefaultKeyEntropyMode = entropyMode;
}

' This method configures the IssuedToken property of the Credentials property of a proxy/channel factory
Public Shared Sub ConfigureIssuedTokenClientCredentials(ByVal cf As ChannelFactory, _
                                                        ByVal cacheTokens As Boolean, _
                                                        ByVal tokenCacheTime As TimeSpan, _
                                                        ByVal renewalPercentage As Integer, _
                                                        ByVal entropyMode As SecurityKeyEntropyMode)
    If cf Is Nothing Then
        Throw New ArgumentNullException("ChannelFactory")
    End If
    ' Set the CacheIssuedTokens property
    With cf.Credentials.IssuedToken
        .CacheIssuedTokens = cacheTokens

        ' Set the MaxIssuedTokenCachingTime property
        .MaxIssuedTokenCachingTime = tokenCacheTime

        ' Set the IssuedTokenRenewalThresholdPercentage property
        .IssuedTokenRenewalThresholdPercentage = renewalPercentage

        ' Set the DefaultKeyEntropyMode property
        .DefaultKeyEntropyMode = entropyMode
    End With
End Sub

Segurança do .NET Framework

Para evitar a possível divulgação de informações confidenciais, os clientes que executam a ferramenta Svcutil.exe para processar metadados de pontos de extremidade federados devem garantir que os endereços de serviço de token de segurança resultantes sejam o esperado. Isso é principalmente importante quando um serviço de token de segurança mostra vários pontos de extremidade, pois a ferramenta Svcutil.exe gera o arquivo de configuração resultante para usar o primeiro ponto de extremidade desse tipo, que pode não ser o que o cliente deve estar usando.

LocalIssuer Obrigatório

Se os clientes tiverem sempre que usar um emissor local, observe: a saída padrão de Svcutil.exe resulta na não utilização do emissor local se o penúltimo serviço de token de segurança na cadeia especificar um endereço de emissor ou endereço de metadados do emissor.

Para obter mais informações sobre como definir as propriedades LocalIssuerAddress, LocalIssuerBinding e LocalIssuerChannelBehaviors da classe IssuedTokenClientCredential, consulte Como configurar um emissor local.

Certificados com escopo

Se os certificados de serviço precisarem ser especificados para se comunicar com qualquer um dos serviços de token de segurança, normalmente, como a negociação de certificados não está sendo usada, eles podem ser especificados usando a propriedade ScopedCertificates da classe X509CertificateRecipientClientCredential. O método SetDefaultCertificate usa Uri e X509Certificate2 como parâmetros. O certificado especificado é usado ao se comunicar com pontos de extremidade no URI especificado. Como alternativa, você pode usar o SetScopedCertificate método para adicionar um certificado à coleção retornada pela propriedade ScopedCertificates.

Observação

A ideia do cliente de certificados com escopo para um determinado URI aplica-se apenas a aplicativos que estão fazendo chamadas de saída para serviços que mostram pontos de extremidade nesses URIs. Não se aplica a certificados que são usados para assinar tokens emitidos, como aqueles configurados no servidor da coleção retornada por KnownCertificates da classe IssuedTokenServiceCredential. Para obter mais informações, consulte Como configurar credenciais em um serviço de federação.

Confira também