Comportamientos de seguridad en WCF

En Windows Communication Foundation (WCF), los comportamientos modifican el comportamiento en tiempo de ejecución en el nivel de servicio o en el nivel de punto de conexión. (Para más información sobre los comportamientos en general, consulte Especificación del comportamiento en tiempo de ejecución del servicio). Los comportamientos de seguridad permiten controlar las credenciales, la autenticación, la autorización y los registros de auditoría. Puede utilizar comportamientos mediante programación o a través de configuración.

Este artículo se centra en la configuración de los siguientes comportamientos relacionados con las funciones de seguridad:

Establecimiento de credenciales con comportamientos

Use <serviceCredentials> y <clientCredentials> para establecer valores de credenciales para un servicio o cliente. La configuración de enlace subyacente determina si una credencial tiene que establecerse. Por ejemplo, si el modo de seguridad está establecido en None, clientes y servicios no se autentican entre sí y no requieren credenciales de ningún tipo.

Por otro lado, el enlace de servicio puede requerir un tipo de credencial de cliente. En ese caso, puede tener que establecer un valor de credencial mediante un comportamiento. (Para más información sobre los tipos de credenciales posibles, consulte Selección de tipos de credenciales). En algunos casos, como cuando se usan credenciales de Windows para autenticar, el entorno establece automáticamente el valor de credencial real y no es necesario establecerlo explícitamente (a menos que quiera especificar un conjunto diferente de credenciales).

Todas las credenciales de servicios se encuentran como elementos secundarios de <serviceBehaviors>. El siguiente ejemplo muestra un certificado utilizado como una credencial de servicio.

<configuration>
 <system.serviceModel>
  <behaviors>
   <serviceBehaviors>
    <behavior name="ServiceBehavior1">
     <serviceCredentials>
      <serviceCertificate findValue="000000000000000000000000000"
                          storeLocation="CurrentUser"
      storeName="Root" x509FindType="FindByThumbprint" />
     </serviceCredentials>
    </behavior>
   </serviceBehaviors>
  </behaviors>
 </system.serviceModel>
</configuration>

Credenciales de servicio

<serviceCredentials> contiene cuatro elementos secundarios. Los elementos y sus usos se discuten en las siguientes secciones.

Elemento <serviceCertificate>

Use este elemento para especificar un certificado X.509 que se usará para autenticar el servicio a los clientes utilizando el modo de seguridad de mensajes. Si está usando un certificado que se renueva periódicamente, su huella digital cambiará. En ese caso, utilice el nombre del asunto como el X509FindType porque el certificado se puede volver a emitir con el mismo nombre de asunto.

Para más información sobre cómo usar el elemento, consulte Cómo especificar los valores de credenciales de cliente.

<certificate> del elemento <clientCertificate>

Use el elemento <certificate> cuando el servicio deba tener de antemano el certificado del cliente para comunicarse de manera segura con el cliente. Esto se produce al utilizar el patrón de comunicación dúplex. En el patrón de solicitud-respuesta más típico, el cliente incluye su certificado en la solicitud, que utiliza el servicio para proteger su respuesta de vuelta hasta el cliente. El patrón de comunicación dúplex, sin embargo, no tiene ninguna solicitud ni respuesta. El servicio no puede inferir el certificado del cliente a partir de la comunicación y, por consiguiente, el servicio necesita tener de antemano el certificado del cliente para proteger los mensajes destinados al cliente. Debe obtener el certificado del cliente de una manera fuera de banda y especificar el certificado usando este elemento. Para más información sobre los servicios dúplex, consulte Cómo crear un contrato dúplex.

<authentication> del elemento <clientCertificate>

El elemento <authentication> le permite personalizar cómo se autentican los clientes. Puede establecer el atributo CertificateValidationMode en None, ChainTrust, PeerOrChainTrust, PeerTrust o Custom. De manera predeterminada, el nivel está establecido en ChainTrust, que especifica que cada certificado se debe encontrar en una jerarquía de certificados que finalizan en una entidad de certificación raíz en la parte superior de la cadena. Este es el modo más seguro. También puede establecer el valor en PeerOrChainTrust, que especifica que los certificados autoemitidos (confianza del mismo nivel) se aceptan, así como los certificados que están en una cadena de confianza. Se utiliza este valor cuando se desarrollan y depuran clientes y servicios porque los certificados autoemitidos no necesitan adquirirse desde una autoridad de confianza. Al implementar un cliente, utilice en su lugar el valor ChainTrust. También puede establecer el valor en Custom. Cuando se establezca en el valor Custom, también debe establecer el atributo CustomCertificateValidatorType en un ensamblado y tipo utilizados para validar el certificado. Para crear su propio validador personalizado, debe heredar a partir de la clase X509CertificateValidator abstracta.

Elemento <issuedTokenAuthentication>

El escenario del token emitido tiene tres etapas. En la primera fase, un cliente que intenta acceder a un servicio se remite a un servicio de token de seguridad (STS). El STS autentica, a continuación, al cliente y como consecuencia el cliente emite un token, normalmente un token del lenguaje de marcado de aserción de seguridad (SAML). El cliente vuelve a continuación al servicio con el token. El servicio examina el token para los datos que permite al servicio autenticar el token y, por consiguiente, al cliente. Para autenticar el token, el servicio debe conocer el certificado que usa el servicio de token seguro. El elemento <issuedTokenAuthentication> es el repositorio para todos los certificados de servicio de token de seguridad. Para agregar certificados, use <knownCertificates>. Inserte <add> para cada certificado, tal como se muestra en el ejemplo siguiente.

<issuedTokenAuthentication>
   <knownCertificates>
      <add findValue="www.contoso.com"
           storeLocation="LocalMachine" storeName="My"
           X509FindType="FindBySubjectName" />
    </knownCertificates>
</issuedTokenAuthentication>

De forma predeterminada, los certificados se deben obtener a partir de un servicio de token de seguridad. Estos certificados "conocidos" garantizan que solo los clientes legítimos pueden obtener acceso a un servicio.

Debería usar la colección <allowedAudienceUris> en una aplicación federada que utilice un servicio de token de seguridad (STS) que emite tokens de seguridad SamlSecurityToken. Cuando el STS emite el token de seguridad, puede especificar el URI de los servicios Web para el que está dirigido el token de seguridad mediante la agregación de una SamlAudienceRestrictionCondition al token de seguridad. Eso le permite al SamlSecurityTokenAuthenticator del servicio Web del destinatario comprobar que el token de seguridad emitido está dirigido a este servicio Web especificando que esta comprobación debería tener lugar haciendo lo siguiente:

  • Establezca el atributo audienceUriMode de <issuedTokenAuthentication> en Always o BearerKeyOnly.

  • Especifique el conjunto de identificadores URI válidos, agregando los URI a esta colección. Para ello, inserte <add> para cada URI.

Para obtener más información, vea SamlSecurityTokenAuthenticator.

Para más información sobre cómo usar este elemento de configuración, consulte el artículo sobre la configuración de credenciales en un servicio de federación.

Permitir usuario anónimos CardSpace

Mediante el establecimiento del atributo AllowUntrustedRsaIssuers del elemento <IssuedTokenAuthentication> en true de manera explícita, se permite a cualquier cliente presentar un token autoemitido firmado con un par de claves de RSA arbitrario. El emisor no es de confianza porque la clave no tiene datos de emisor asociados. Un usuario de CardSpace puede crear una tarjeta autoemitida que incluya notificaciones de identidad autoproporcionadas. Utilice esta función con precaución. Para usar esta característica, piense en la clave pública de RSA como una contraseña más segura que debería almacenarse en una base de datos junto con un nombre de usuario. Antes de permitir que un cliente obtenga acceso al servicio, compruebe la clave pública de RSA presentada por el cliente comparándola con la clave pública almacenada para el nombre de usuario presentado. Esto supone que ha establecido con que un proceso de registro por el que los usuarios pueden registrar sus nombres de usuario y asociarlos con las claves públicas de RSA autoemitidas.

Credenciales de cliente

Las credenciales de cliente se utilizan para autenticar al cliente en los servicios en casos donde se requiere autenticación mutua. Puede utilizar la sección para especificar los certificados de servicio para escenarios donde el cliente debe proteger los mensajes para un servicio con el certificado del servicio.

También puede configurar un cliente como parte de un escenario de federación para usar tokens emitidos a partir de un servicio de tokens seguros o un emisor local de tokens. Para obtener más información sobre escenarios federados, consulte Federación y tokens emitidos. Todas las credenciales de cliente se encuentran bajo <endpointBehaviors>, tal como se muestra en el código siguiente.

<behaviors>
 <endpointBehaviors>
  <behavior name="EndpointBehavior1">
   <clientCredentials>
    <clientCertificate findValue="cn=www.contoso.com"
        storeLocation="LocalMachine"
        storeName="AuthRoot" x509FindType="FindBySubjectName" />
    <serviceCertificate>
     <defaultCertificate findValue="www.cohowinery.com"
                    storeLocation="LocalMachine"
                    storeName="Root" x509FindType="FindByIssuerName" />
    <authentication revocationMode="Online"
                    trustedStoreLocation="LocalMachine" />
    </serviceCertificate>
   </clientCredentials>
  </behavior>
 </endpointBehaviors>
</behaviors>

Elemento <clientCertificate>

Establezca el certificado utilizado para autenticar al cliente con este elemento. Para más información, consulte el artículo sobre cómo especificar valores de credenciales de cliente.

<httpDigest>

Esta característica se debe habilitar con Active Directory en Windows e Internet Information Services (IIS). Para más información, consulte el artículo sobre la autenticación implícita en IIS 6.0.

Elemento <issuedToken>

<issuedToken> contiene los elementos que se utilizan para configurar un emisor local de tokens, o los comportamientos utilizados con un servicio de token de seguridad. Para instrucciones sobre cómo configurar un cliente para usar un emisor local, consulte el procedimiento para configurar un emisor local.

<localIssuerAddress>

Especifica una dirección de servicio de token de seguridad predeterminada. Esto se utiliza cuando WSFederationHttpBinding no proporciona una dirección URL para el servicio de token de seguridad o cuando la dirección del emisor de un enlace federado es http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous o null. En casos como éste, las ClientCredentials deben configurarse con la dirección del emisor local y el enlace que se va a utilizar para comunicarse con ese emisor.

<issuerChannelBehaviors>

Utilice <issuerChannelBehaviors> para agregar comportamientos de cliente de WCF que se utilizan al comunicarse con un servicio de token de seguridad. Defina comportamientos de cliente en la sección <endpointBehaviors>. Para utilizar un comportamiento definido, agregue un elemento <add> al elemento <issuerChannelBehaviors> con dos atributos. Establezca la issuerAddress en la dirección URL del servicio de token de seguridad y establezca el atributo behaviorConfiguration en el nombre del comportamiento del punto de conexión definido, tal y como se muestra en el ejemplo siguiente.

<clientCredentials>
   <issuedToken>
      <issuerChannelBehaviors>
         <add issuerAddress="http://www.contoso.com"
               behaviorConfiguration="clientBehavior1" />
      </issuerChannelBehaviors>
   </issuedToken>
</clientCredentials>

Elemento <serviceCertificate>

Utilice este elemento para controlar autenticación de certificados de servicio.

El elemento <defaultCertificate> pueden almacenar un certificado único que se utiliza cuando el servicio no especifica ningún certificado.

Utilice <scopedCertificates> y <add> para establecer certificados de servicio asociados a servicios específicos. El elemento <add> incluye un atributo targetUri que se utilice para asociar el certificado al servicio.

El elemento <authentication> especifica el nivel de confianza que se utiliza para autenticar certificados. De forma predeterminada, el nivel está establecido en "ChainTrust", que especifica que cada certificado debe encontrarse en una jerarquía de certificados que finalizan en una entidad emisora de certificados de confianza en la parte superior de la cadena. Este es el modo más seguro. También puede establecer el valor en “PeerOrChainTrust”, que especifica que los certificados autoemitidos (confianza de mismo nivel) se aceptan, así como los certificados que están en una cadena de confianza. Se utiliza este valor cuando se desarrollan y depuran clientes y servicios porque los certificados autoemitidos no necesitan adquirirse desde una autoridad de confianza. Al implementar un cliente, utilice en su lugar el valor “ChainTrust”. También puede establecer el valor en "Custom" o "None". Para usar el valor "Custom", también debe establecer el atributo CustomCertificateValidatorType en un ensamblado y tipos que se utilizan para validar el certificado. Para crear su propio validador personalizado, debe heredar a partir de la clase X509CertificateValidator abstracta. Para más información, consulte el artículo sobre cómo crear un servicio que emplee un validador de certificado personalizado.

El elemento <authentication> incluye un atributo RevocationMode que especifica cómo se comprueba la revocación de los certificados. El valor predeterminado es "online", que indica que la revocación de los certificados se comprueba automáticamente. Para más información, consulte Trabajar con certificados.

ServiceAuthorization

El elemento <serviceAuthorization> contiene elementos que afectan a la autorización, los proveedores de roles personalizados y la suplantación.

La clase PrincipalPermissionAttribute se aplica a un método de servicio. El atributo especifica los grupos de usuarios que se han de utilizar al autorizar el uso de un método protegido. El valor predeterminado es "UseWindowsGroups" y especifica que en los grupos de Windows, como "Administradores" o "Usuarios", se busca una identidad que intente obtener acceso a un recurso. También puede especificar "UseAspNetRoles" para usar un proveedor de roles personalizados que se configura bajo el elemento <system.web>, tal como se muestra en el código siguiente.

<system.web>
  <membership defaultProvider="SqlProvider"
   userIsOnlineTimeWindow="15">
     <providers>
       <clear />
       <add
          name="SqlProvider"
          type="System.Web.Security.SqlMembershipProvider"
          connectionStringName="SqlConn"
          applicationName="MembershipProvider"
          enablePasswordRetrieval="false"
          enablePasswordReset="false"
          requiresQuestionAndAnswer="false"
          requiresUniqueEmail="true"
          passwordFormat="Hashed" />
     </providers>
   </membership>
  <!-- Other configuration code not shown.-->
</system.web>

El ejemplo de código siguiente muestra el roleProviderName utilizado con el atributo principalPermissionMode.

<behaviors>
 <behavior name="ServiceBehaviour">
  <serviceAuthorization principalPermissionMode ="UseAspNetRoles"
                        roleProviderName ="SqlProvider" />
</behavior>
   <!-- Other configuration code not shown. -->
</behaviors>

Configuración de agentes de seguridad

Utilice <serviceSecurityAudit> para especificar el registro en el que se escribirá y qué tipos de eventos se registrarán. Para más información, consulte Auditoría.

<behaviors>
 <serviceBehaviors>
  <behavior name="NewBehavior">
    <serviceSecurityAudit auditLogLocation="Application"
             suppressAuditFailure="true"
             serviceAuthorizationAuditLevel="Success"
             messageAuthenticationAuditLevel="Success" />
  </behavior>
 </serviceBehaviors>
</behaviors>

Intercambio seguro de metadatos

Exportar los metadatos a los clientes es conveniente para los desarrolladores de clientes y servicios, puesto que permite la descarga de configuración y código de cliente. Para reducir la exposición de un servicio a los usuarios malintencionados, es posible proteger la transferencia mediante el mecanismo SSL sobre HTTP (HTTPS). Para realizar esto, debe enlazar primero un certificado X.509 adecuado a un puerto concreto en el equipo que esté hospedando el servicio. (Para más información, consulte Trabajar con certificados). En segundo lugar, agregue <serviceMetadata> a la configuración del servicio y establezca el atributo HttpsGetEnabled en true. Finalmente, establezca el atributo HttpsGetUrl en la dirección URL del punto de conexión de metadatos del servicio, tal y como se muestra en el ejemplo siguiente.

<behaviors>
 <serviceBehaviors>
  <behavior name="NewBehavior">
    <serviceMetadata httpsGetEnabled="true"
     httpsGetUrl="https://myComputerName/myEndpoint" />
  </behavior>
 </serviceBehaviors>
</behaviors>

Consulte también