Procedimiento para crear un cliente federado

En Windows Communication Foundation (WCF), la creación de un cliente para un servicio federado consta de tres pasos principales:

  1. Configure un enlace <wsFederationHttpBinding> o un enlace personalizado similar. Para más información sobre cómo crear un enlace adecuado, consulte Procedimiento para crear un WSFederationHttpBinding. Alternativamente, ejecute la Herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) en el punto de conexión de metadatos del servicio federado para generar un archivo de configuración para comunicarse con el servicio federado y uno o más servicios de tokens de seguridad.

  2. Establezca las propiedades de la IssuedTokenClientCredential que controla varios aspectos de la interacción de un cliente con un servicio de tokens de seguridad.

  3. Establezca las propiedades de la X509CertificateRecipientClientCredential, que permite que los certificados necesarios para comunicarse de manera segura con extremos determinados, como servicios de tokens de seguridad.

Nota

Se podría iniciar una CryptographicException cuando un cliente utiliza credenciales suplantadas, el enlace WSFederationHttpBinding o un token emitido personalizado, y claves asimétricas. Las claves asimétricas se utilizan con el enlace WSFederationHttpBinding y tokens emitidos personalizados cuando las propiedades IssuedKeyType y KeyType, respectivamente, están establecidas en AsymmetricKey. Se inicia CryptographicException cuando el cliente intenta enviar un mensaje y no existe un perfil de usuario para la identidad que el cliente está suplantando. Para mitigar este problema, inicie sesión en el equipo cliente o llame a LoadUserProfile antes de enviar el mensaje.

Este tema proporciona información detallada sobre estos procedimientos. Para más información sobre cómo crear un enlace adecuado, consulte Procedimiento para crear un WSFederationHttpBinding. Para más información sobre cómo funciona un servicio federado, consulte Federación.

Generar y examinar la configuración para un servicio federado

  1. Ejecute la Herramienta de utilidad de metadatos de ServiceModel (Svcutil.exe) con la dirección de la URL de metadatos del servicio como un parámetro de línea de comandos.

  2. Abra el archivo de configuración generado en un editor adecuado.

  3. Examine los atributos y el contenido de los elementos generados <issuer> e <issuerMetadata>. Se encuentran en los elementos <security> del <wsFederationHttpBinding> o elementos de enlace personalizados. Asegúrese de que las direcciones contienen los nombres de dominio esperados u otra información de dirección. Es importante comprobar esta información porque el cliente se autentica en estas direcciones y podría revelar información como pares de nombre de usuario y contraseña. Si la dirección no es la dirección esperada, podría revelarse información en un destinatario incorrecto.

  4. Examine cualquier elemento adicional <issuedTokenParameters> dentro del elemento <alternativeIssuedTokenParameters> marcado con comentarios. Al utilizar la herramienta Svcutil.exe para generar la configuración de un servicio federado, si el servicio federado o cualquier servicio de tokens de seguridad intermedio no especifican una dirección de emisor, sino que especifican una dirección de metadatos para un servicio de tokens de seguridad que expone varios puntos de conexión, el archivo de configuración resultante hace referencia al primer punto de conexión. Los puntos de conexión adicionales están en el archivo de configuración como elementos <alternativeIssuedTokenParameters> marcados con comentarios.

    Determine si uno de estos parámetros <issuedTokenParameters> se prefiere en lugar del que ya está presente en la configuración. Por ejemplo, el cliente puede preferir autenticar a un servicio de tokens de seguridad utilizando un token de CardSpace de Windows en lugar de mediante un par de nombre de usuario y contraseña.

    Nota

    Un servicio de tokens de seguridad intermedio puede dirigir el cliente a un servicio de tokens de seguridad incorrecto si se deben atravesar varios servicios de tokens de seguridad antes de comunicarse con el servicio. Por consiguiente, asegúrese de que el punto de conexión del servicio de tokens de seguridad en los <issuedTokenParameters> es el servicio de tokens de seguridad esperado y no un servicio de tokens de seguridad desconocido.

Configuración de una IssuedTokenClientCredential mediante código

  1. Obtenga acceso a la IssuedTokenClientCredential mediante la propiedad IssuedToken de la clase ClientCredentials (devuelta por la propiedad ClientCredentials de la clase ClientBase<TChannel>, o a través de la clase ChannelFactory), tal y como se muestra en el siguiente código de muestra.

    IssuedTokenClientCredential itcc = client.ClientCredentials.IssuedToken;
    
    Dim itcc As IssuedTokenClientCredential = client.ClientCredentials.IssuedToken
    
  2. Si no se requiere el almacenamiento en caché de tokens, establezca la propiedad CacheIssuedTokens en false. La propiedad CacheIssuedTokens controla si esos tokens de un servicio de tokens de seguridad están almacenados en memoria caché. Si esta propiedad está establecida en false, el cliente solicita un nuevo token del servicio de tokens de de seguridad cada vez que se tenga que volver a autenticar en el servicio federado, sin tener en cuenta si un token anterior aún es válido. Si esta propiedad está establecida en true, el cliente reutiliza un token existente cada vez que se debe volver a autenticar en el servicio federado (siempre que el token no se haya caducado). El valor predeterminado es true.

  3. Si se requiere un límite horario en tokens almacenados en memoria caché, establezca la propiedad MaxIssuedTokenCachingTime en un valor TimeSpan. La propiedad especifica cuánto tiempo puede estar un token almacenado en memoria caché. Después de que el intervalo de tiempo especificado haya transcurrido, el token se quita de la caché del cliente. De forma predeterminada, los tokens se almacenan en memoria caché indefinidamente. El siguiente ejemplo establece el intervalo de tiempo en 10 minutos.

    itcc.MaxIssuedTokenCachingTime = new TimeSpan(0, 10, 0);
    
    itcc.MaxIssuedTokenCachingTime = New TimeSpan(0, 10, 0)
    
  4. Opcional. Establezca el IssuedTokenRenewalThresholdPercentage en un porcentaje. El valor predeterminado es 60 (por ciento). La propiedad especifica un porcentaje del período de validez del token. Por ejemplo, si el token emitido es válido durante 10 horas y IssuedTokenRenewalThresholdPercentage se establece en 80, el token se renovará después de ocho horas. El siguiente ejemplo establece el valor en 80 por ciento.

    itcc.IssuedTokenRenewalThresholdPercentage = 80;
    
    itcc.IssuedTokenRenewalThresholdPercentage = 80
    

    El intervalo de renovación determinado por el período de validez del token y el valor IssuedTokenRenewalThresholdPercentage es invalidado por el valor MaxIssuedTokenCachingTime en casos donde el tiempo de almacenamiento en caché es menor que el tiempo límite de renovación. Por ejemplo, si el producto de IssuedTokenRenewalThresholdPercentage y la duración del token es de ocho horas, y el valor de MaxIssuedTokenCachingTime es de 10 minutos, el cliente se pone en contacto con el servicio de tokens de seguridad de un token actualizado cada 10 minutos.

  5. Si es necesario un modo de entropía de clave distinto de CombinedEntropy en un enlace que no utiliza seguridad de mensaje o seguridad de transporte con credenciales de mensajes (por ejemplo, el enlace no tiene un SecurityBindingElement), establezca la propiedad DefaultKeyEntropyMode en un valor adecuado. El modo de entropía determina si las claves simétricas se pueden controlar mediante la propiedad DefaultKeyEntropyMode. Este valor predeterminado es CombinedEntropy, donde el cliente y el emisor de tokens proporcionan datos que se combinan para generar la clave real. Otros valores son ClientEntropy y ServerEntropy, que quieren decir que el cliente o el servidor, respectivamente, especifican la clave al completo. El siguiente ejemplo establece la propiedad para utilizar solo los datos del servidor para la clave.

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

    Nota

    Si se encuentra presente un SecurityBindingElement en un servicio de tokens de seguridad o enlace de servicio, el DefaultKeyEntropyMode establecido en IssuedTokenClientCredential es invalidado por la propiedad KeyEntropyMode del SecurityBindingElement.

  6. Configure los comportamientos de punto de conexión específicos del emisor agregándolos a la colección devuelta por la propiedad IssuerChannelBehaviors.

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

Configuración de la IssuedTokenClientCredential mediante configuración

  1. Cree un elemento <issuedToken> como elemento secundario del elemento <issuedToken> en un comportamiento de punto de conexión.

  2. Si no se requiere el almacenamiento en caché de tokens, establezca el atributo cacheIssuedTokens (del elemento <issuedToken>) en false.

  3. Si es necesario un límite de tiempo en los tokens almacenados en memoria caché, establezca el atributo maxIssuedTokenCachingTime del elemento <issuedToken> en un valor adecuado. Por ejemplo:
    <issuedToken maxIssuedTokenCachingTime='00:10:00' />

  4. Si se prefiere un valor que no sea el valor predeterminado, establezca el atributo issuedTokenRenewalThresholdPercentage del elemento <issuedToken> en un valor adecuado, por ejemplo:

    <issuedToken issuedTokenRenewalThresholdPercentage = "80" />  
    
  5. Si un modo de entropía de clave distinto de CombinedEntropy está en un enlace que no utiliza seguridad de mensaje o seguridad de transporte con credenciales de mensaje (por ejemplo, el enlace no tiene un SecurityBindingElement), establezca el atributo defaultKeyEntropyMode del elemento <issuedToken>ServerEntropy, según se requiera.

    <issuedToken defaultKeyEntropyMode = "ServerEntropy" />  
    
  6. Opcional. Configure cualquier comportamiento de punto de conexión personalizado específico del emisor mediante la creación de un elemento <issuerChannelBehaviors> como elemento secundario del elemento <issuedToken>. Para cada comportamiento, cree un elemento <add> como elemento secundario del elemento <issuerChannelBehaviors>. Especifique la dirección del emisor del comportamiento mediante el establecimiento del atributo issuerAddress del elemento <add>. Especifique el propio comportamiento mediante el establecimiento del atributo behaviorConfiguration del elemento <add>.

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

Configuración de una X509CertificateRecipientClientCredential mediante código

  1. Obtenga acceso a la X509CertificateRecipientClientCredential a través de la propiedad ServiceCertificate de la propiedad ClientCredentials de la clase ClientBase<TChannel> o la propiedad ChannelFactory.

    X509CertificateRecipientClientCredential rcc =
        client.ClientCredentials.ServiceCertificate;
    
    Dim rcc As X509CertificateRecipientClientCredential = _
    client.ClientCredentials.ServiceCertificate
    
  2. Si una instancia de X509Certificate2 está disponible para el certificado de un punto de conexión determinado, utilice el método Add de la colección devuelto por la propiedad ScopedCertificates.

    rcc.ScopedCertificates.Add(new Uri("http://fabrikam.com/sts"), cert);
    
    rcc.ScopedCertificates.Add(New Uri("http://fabrikam.com/sts"), cert)
    
  3. Si una instancia X509Certificate2 no está disponible, utilice el método SetScopedCertificate de la clase X509CertificateRecipientClientCredential como se muestra en el ejemplo siguiente.

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

Configuración de una X509CertificateRecipientClientCredential mediante configuración

  1. Cree un elemento <scopedCertificates> como elemento secundario del elemento <serviceCertificate>, que a su vez es un elemento secundario del elemento <clientCredentials> en un comportamiento del punto de conexión.

  2. Cree un elemento <add> como elemento secundario del elemento <scopedCertificates>. Especifique valores para los atributos storeLocation, storeName, x509FindTypey findValue para hacer referencia al certificado adecuado. Establezca el atributo targetUri en un valor que proporcione la dirección del extremo para la que se ha de utilizar el certificado, tal y como se muestra en el siguiente ejemplo.

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

Ejemplo

El siguiente ejemplo de código configura una instancia de la clase IssuedTokenClientCredential mediante 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

Seguridad de .NET Framework

Para evitar la posible divulgación de la información, los clientes que están ejecutando la herramienta Svcutil.exe para procesar los metadatos desde puntos de conexión federados deberían asegurarse de que las direcciones del servicio de tokens de seguridad resultantes son las esperadas. Esto es especialmente importante cuando un servicio de tokens de seguridad expone varios puntos de conexión, porque la herramienta Svcutil.exe genera el archivo de configuración resultante para utilizar el primero de esos puntos de conexión, que no puede ser el que el cliente debería estar utilizando.

LocalIssuer requerido

Si se espera que los clientes utilicen siempre un emisor local, tenga en cuenta lo siguiente: la salida predeterminada de Svcutil.exe hace que no se utilice el emisor local si el servicio de tokens de seguridad de segundo a último en la cadena especifica una dirección de emisor o una dirección de metadatos de emisor.

Para más información sobre cómo establecer las propiedades LocalIssuerAddress, LocalIssuerBindingy LocalIssuerChannelBehaviors de la clase IssuedTokenClientCredential, consulte Configuración de un emisor local.

Certificados con ámbito

Si los certificados del servicio se deben especificar para comunicarse con cualquiera de los servicios de tokens de seguridad, normalmente debido a que no se utiliza la negociación de certificados, se pueden especificar mediante la propiedad ScopedCertificates de la clase X509CertificateRecipientClientCredential. El método SetDefaultCertificate toma un Uri y un X509Certificate2 como parámetros. Se utiliza el certificado especificado al comunicarse con puntos de conexión en el URI especificado. De manera alternativa, puede utilizar el método SetScopedCertificate para agregar un certificado a la colección devuelta por la propiedad ScopedCertificates.

Nota

La idea del cliente con respecto a los certificados que tienen su ámbito restringido a un URI determinado solo se aplica en aplicaciones que están realizando llamadas salientes a servicios que exponen los extremos en esos URI. No se aplica a certificados que se utilizan para firmar tokens emitidos, como aquellos configurados en el servidor en la colección devuelta por KnownCertificates de la clase IssuedTokenServiceCredential. Para más información, consulte Configuración de credenciales en un servicio de federación.

Consulte también