Esta documentación está archivada y no tiene mantenimiento.

Procedimiento: Solicitar un token de ACS mediante el protocolo OAuth WRAP

Actualizado: junio de 2015

  • Active Directory Access Control de Microsoft Azure (también conocido como Access Control Service o ACS)

Cuando los servicios y aplicaciones web controlan la autenticación mediante ACS, el cliente debe obtener un token de seguridad emitido por ACS para iniciar sesión en la aplicación o servicio. Para obtener este token emitido por ACS (token de salida), el cliente debe autenticar directamente con ACS o enviar a ACS un token de seguridad emitido por el proveedor de su identidad (token de entrada). ACS valida este token de seguridad de entrada, procesa las notificaciones de identidad de este token a través del motor de reglas ACS, calcula las notificaciones de identidad de salida y emite un token de seguridad de salida.

En este tema se describen los métodos para solicitar un token de ACS a través del protocolo OAuth WRAP. Todas las solicitudes de tokens mediante el protocolo OAuth WRAP se transmiten a través de SSL. ACS siempre emite un token de web simple (SWT) mediante el protocolo OAuth WRAP, en respuesta a una solicitud de token con el formato correcto. Todas las solicitudes de tokens mediante el protocolo OAuth WRAP se envían a ACS en una solicitud HTTP POST. Puede solicitar un token de ACS mediante el protocolo OAuth WRAP desde cualquier plataforma que puede realizar un formulario HTTPS POST: .NET Framework, Windows Communication Foundation (WCF), Silverlight, ASP.NET, Java, Python, Ruby, PHP, Flash y otras plataformas.

En la tabla siguiente se muestran tres métodos admitidos para solicitar un token SWT emitido por ACS mediante el protocolo OAuth WRAP.

Tres métodos para solicitar un token de ACS mediante el protocolo OAuth WRAP

Método de solicitud de token Descripción

Solicitudes de token de contraseña

Este sencillo método requiere que el cliente envíe un nombre de usuario y una contraseña desde una identidad de servicio directamente a ACS a través del protocolo OAuth WRAP para la autenticación.

Solicitudes de token de SWT

Este método requiere que el cliente envíe un token SWT que puede estar firmado con una clave simétrica de identidad de servicio o una clave simétrica de proveedor de identidad a ACS a través del protocolo OAuth WRAP para la autenticación.

Solicitudes de token de SAML

Destinado principalmente a la integración de Servicios de federación de Active Directory (ADFS) 2.0, el método del lenguaje de marcado de aserción de seguridad (SAML) requiere que el cliente envíe un token SAML firmado a ACS a través del protocolo OAuth WRAP para la autenticación. Este enfoque permite al cliente usar una identidad de empresa para autenticar con ACS.

Todas las solicitudes de token de ACS mediante el protocolo OAuth WRAP están dirigidas a un extremo de emisión de tokens ACS. El URI de este extremo depende de Espacio de nombres Access Control. El espacio de nombres aparece como un prefijo de nombre DNS en un URI de solicitud de token. El resto del nombre del DNS es fijo, como la ruta de acceso. Por ejemplo, si desea solicitar un token de Espacio de nombres Access Control llamado "mysnservice", puede dirigir una solicitud de token para el URI siguiente: https://mysnservice.accesscontrol.windows.net/WRAPv0.9.

Con una solicitud de token de contraseña, un cliente puede enviar un nombre de usuario y una contraseña desde una identidad de servicio directamente a ACS a través del protocolo OAuth WRAP para la autenticación. Se trata de la manera más fácil de solicitar un token de ACS mediante el protocolo OAuth WRAP. Aparte de establecer una conexión SSL, este enfoque no requiere ninguna capacidad de cifrado. En la práctica, es similar al modelo de usuario/contraseña que es frecuente en servicios web REST. Este tipo de solicitud de token es realmente un formulario HTTPS POST. Los parámetros de una solicitud de token de contraseña están codificados por formulario.

El siguiente es un ejemplo de un seguimiento de la conexión de una solicitud de texto simple a un espacio de nombres denominado "mysnservice".

POST /WRAPv0.9/ HTTP/1.1
Host: mysnservice.accesscontrol.windows.net
Content-Type: application/x-www-form-urlencoded

wrap_scope=http%3A%2F%2Fmysnservice.com%2Fservices%2F&
wrap_name=mysncustomer1&
wrap_password=5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ%3D

En la tabla siguiente se proporcionan los nombres, descripciones y requisitos de valor de los parámetros que deben estar presentes en una solicitud de token de contraseña:

 

Nombre de parámetro Descripción Requisitos de valor

wrap_scope

Hace coincidir la solicitud de token con un conjunto de reglas. Establezca el valor de este parámetro al valor del dominio de la aplicación del usuario de confianza. Puede obtener este valor (en el campo Dominio kerberos) a través del Portal de administración de ACS mediante la selección de la aplicación del usuario de confianza desde la página Aplicaciones del usuario de confianza.

  • URI de HTTP(s) o HTTP

  • No hay parámetros de consulta o delimitadores.

  • Segmentos de ruta de acceso <= 32.

  • Longitud máxima: 256 caracteres.

  • Debe ser la dirección URL codificada.

wrap_name

Valida la clave del parámetro siguiente. Establezca el valor de este parámetro en el nombre de una identidad de servicio en su Espacio de nombres Access Control. Puede obtener este valor (en el campo Nombre) a través del Portal de administración de ACS mediante la selección de la identidad de servicio adecuada desde la página Identidades de servicio.

  • Longitud mínima: 1 carácter.

  • Longitud máxima: 128 caracteres.

  • Debe ser la dirección URL codificada.

wrap_password

Autentica la solicitud entrante. Establezca el valor de este parámetro en la contraseña de una identidad de servicio en su Espacio de nombres Access Control. Puede obtener este valor (en el campo Contraseña en la página Editar credencial), a través del Portal de administración de ACS, primero seleccionando la identidad de servicio adecuada en la página Identidades de servicio y, a continuación, seleccionando la contraseña correspondiente en la tabla Credenciales de la página Editar identidad de servicio.

  • Cadena, un mínimo de 1 y un máximo de 64 caracteres de longitud.

  • Debe ser la dirección URL codificada.

Los valores de estos parámetros deben codificarse para URL antes de enviar la solicitud a ACS. La aplicación o servicio web puede proporcionar el valor de wrap_scope al cliente, o el cliente puede optar por establecer el valor del parámetro wrap_scope al URI del destino del recurso del servicio o la aplicación web.

Las solicitudes de tokens de contraseña mediante el protocolo OAuth WRAP también pueden contener parámetros adicionales que ACS puede usar durante el proceso de cálculo de notificaciones de salida. Estos nombres de parámetros adicionales y los valores deben codificarse para URL y los valores no deben estar entre comillas.

El método de solicitud de token de contraseña es bastante sencillo con .

WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "mysncustomer1");
values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
values.Add("wrap_scope", "http://mysnservice.com/services");

// WebClient takes care of the URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);

Para obtener información sobre cómo desempaquetar el token de salida de ACS y enviarlo a la aplicación o servicio web, vea Unwrapping and sending the token to a web application or service.

También puede solicitar un token de ACS a través del protocolo OAuth WRAP mediante un token de SWT firmado por una clave simétrica. Todas las solicitudes de tokens de SWT se realizan a través de un formulario HTTPS POST. Los valores de parámetro de este método de solicitud de token están codificados para formulario.

El siguiente es un ejemplo de un seguimiento de la conexión de una solicitud de token de SWT en el espacio de nombres "mysnservice".

POST /WRAPv0.9/ HTTP/1.1
Host: mysnservice.accesscontrol.windows.net
Content-Type: application/x-www-form-urlencoded

wrap_scope=http%3A%2F%2Fmysnservice.com%2Fservices%2F&
wrap_assertion_format=SWT&
wrap_assertion=Issuer%3dmysncustomer1%26HMACSHA256%3db%252f%252bJFwbngGdufECFjQb8qhb9YH0e32Cf9ABMDZFiPPA%253d

Una solicitud de token de SWT debe tener los siguientes parámetros y valores:

 

Nombre de parámetro Descripción Requisitos de valor

wrap_scope

Hace coincidir la solicitud de token con un conjunto de reglas.

  • Establezca el valor de este parámetro al valor del dominio de la aplicación del usuario de confianza. Puede obtener este valor (en el campo Dominio kerberos) a través del Portal de administración de ACS mediante la selección de la aplicación del usuario de confianza desde la página Aplicaciones del usuario de confianza.

  • URI de HTTP(s) o HTTP.

  • No hay parámetros de consulta o delimitadores.

  • Segmentos de ruta de acceso <= 32.

  • Longitud máxima: 256 caracteres.

  • Debe codificarse para URL.

wrap_assertion

Este es el token de entrada que se envía a ACS.

  • Un token de SWT firmado con notificaciones de entrada que incluyen parámetros HMACSHA256 y emisor.

  • Longitud máxima: 2048 caracteres.

  • Debe codificarse para URL.

wrap_assertion_format

Este es el formato del token de entrada que se envía a ACS.

SWT

Como se muestra en el ejemplo siguiente, el código necesario para realizar una solicitud de token de SWT es similar al código necesario para realizar una solicitud de token de contraseña.

WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

NameValueCollection values = new NameValueCollection();
// add the wrap_scope
values.Add("wrap_scope", "http://mysnservice.com/services");
// add the format
values.Add("wrap_assertion_format", "SWT");
// add the SWT
values.Add("wrap_assertion", "Issuer=mysncustomer1&HMACSHA256=b%2f%2bJFwbngGdufECFjQb8qhb9YH0e32Cf9ABMDZFiPPA%3d");
// WebClient takes care of the remaining URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);

Para obtener información sobre cómo desempaquetar la respuesta de ACS y enviarla a la aplicación o servicio web, consulte Unwrapping and sending the token to a web application or service.

Un token de SWT es un conjunto de pares clave/valor que están firmados con una clave de emisor (una clave simétrica). Un token de SWT enviado a ACS en una solicitud de token de SWT, debe contener los parámetros Emisor y HMACSHA256, así como los parámetros adicionales, por ejemplo, ExpiresOn, Audience y otras notificaciones específicas del cliente. En la tabla siguiente se proporcionan los nombres y descripciones de los parámetros de token de SWT:

 

Nombre de parámetro Descripción

Issuer

En ACS, busca la clave que se usó para firmar el token. Si la firma es válida, este valor se usa para realizar el cálculo de la notificación de salida.

Puede establecer este parámetro en el valor del territorio de un proveedor de identidad en su Espacio de nombres Access Control o el nombre de una identidad de servicio en su Espacio de nombres Access Control. Puede obtener este valor (en el campo Territorio en la página Editar proveedor de identidades) a través del Portal de administración de ACS, mediante la selección del proveedor de identidad adecuada en la página Proveedores de identidad. O puede obtener este valor mediante el Servicio de administración de ACS: se trata de la propiedad nombre del registro "Emisor" que se crea para cada proveedor de identidad.

HMACSHA256

En ACS, valida la firma de SWT y busca la clave de emisor nombrada en el parámetro Emisor.

La firma de SWT se crea mediante la clave de firma simétrica conectada a una identidad de servicio o un proveedor de identidad en Espacio de nombres Access Control.

Público

Si está presente, ACS usa este valor para asegurarse de que ACS es el destino del token de SWT. Se trata de la dirección URL de su Espacio de nombres Access Control, por ejemplo, https://contoso.accesscontrol.windows.net/

ExpiresOn

Si está presente (en tiempo base), indica si el token ha caducado. Por ejemplo, el valor de este parámetro puede ser 1324300962.

Notificaciones adicionales

Si está presente, ACS usa estos parámetros para realizar el cálculo de la notificación de salida. Cada tipo de notificación debe aparecer solo una vez. Varios valores de notificación del mismo tipo de notificación se deben concatenar con una "," (coma). Para obtener más información sobre la afirmación de notificación en ACS, vea Aserción de notificaciones a través del protocolo OAuth WRAP.

En el ejemplo de código siguiente se muestra cómo generar un token de SWT mediante . Contiene un tipo que genera tokens de SWT que contienen los parámetros Emisor y HMACSHA256.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;

public class TokenFactory
{
    string signingKey;   
    string issuer;
    
    public TokenFactory(string issuer, string signingKey)
    {
        this.issuer = issuer;
        this.signingKey = signingKey;
    }

    public string CreateToken()
    {
        StringBuilder builder = new StringBuilder();

        // add the issuer name
        builder.Append("Issuer=");
        builder.Append(HttpUtility.UrlEncode(this.issuer));

        string signature = this.GenerateSignature(builder.ToString(), this.signingKey);
        builder.Append("&HMACSHA256=");
        builder.Append(signature);

        return builder.ToString();
    }

   
    private string GenerateSignature(string unsignedToken, string signingKey)
    {
        HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(signingKey));

        byte[] locallyGeneratedSignatureInBytes = hmac.ComputeHash(Encoding.ASCII.GetBytes(unsignedToken));

        string locallyGeneratedSignature = HttpUtility.UrlEncode(Convert.ToBase64String(locallyGeneratedSignatureInBytes));

        return locallyGeneratedSignature;
    }
}

El método de solicitud de token de SAML está pensado principalmente para la integración de AD FS 2.0 y permite al cliente usar una identidad de la empresa (Active Directory) para autenticar con ACS. Con el método de solicitud de token de SAML, puede enviar un token de SAML 1.1 o de SAML 2.0 firmado emitido por AD FS 2.0 (token de entrada) a ACS a través del protocolo OAuth WRAP.

ACS usa sus reglas para calcular las notificaciones de salida, las agrupa en un token de SWT (token de salida), lo firma y devuelve al cliente a través del protocolo OAuth WRAP.

Una solicitud de token de SAML debe tener los siguientes parámetros y valores:

 

Nombre de parámetro Descripción Requisitos de valor

wrap_scope

Hace coincidir la solicitud de token con un conjunto de reglas.

  • Establezca el valor de este parámetro al valor del dominio de la aplicación del usuario de confianza. Puede obtener este valor (en el campo Dominio kerberos) a través del Portal de administración de ACS mediante la selección de la aplicación del usuario de confianza desde la página Aplicaciones del usuario de confianza.

  • URI de HTTP(s) o HTTP.

  • No hay parámetros de consulta o delimitadores.

  • Segmentos de ruta de acceso <= 32.

  • Longitud máxima: 256 caracteres.

  • Debe codificarse para URL.

wrap_assertion

Este es el token de entrada que se envía a ACS.

  • Un token de SAML 1.1 o 2.0 firmado con notificaciones de entrada. Los tokens de SAML 1.1, como una limitación de token, requieren al menos una notificación de entrada. Esto significa que debe usarse un proveedor de identidad o una identidad de servicio habilitada para notificaciones para la autenticación de token de SAML 1.1. Los tokens de SAML 2.0 no requieren ninguna notificación de entrada para la autenticación con una identidad de servicio, además de la notificación de NameIdentifier implícita; por lo tanto, los tokens de SAML 2.0 pueden usarse para autenticar con una identidad de servicio normal que no está habilitada para notificaciones.

  • Debe codificarse para URL.

wrap_assertion_format

Este es el formato del token de entrada que se envía a ACS.

SAML

El siguiente es un ejemplo del código que se requiere para hacer una solicitud de token de SAML.

private static string SendSAMLTokenToACS(string samlToken)
{
 try
 {
  WebClient client = new WebClient();
  client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");
  NameValueCollection parameters = new NameValueCollection();
  parameters.Add("wrap_assertion_format", "SAML");
  parameters.Add("wrap_assertion", samlToken);
  parameters.Add("wrap_scope", "http://mysnservice.com/services");

  byte[] responseBytes = client.UploadValues("WRAPv0.9", parameters);
  string response = Encoding.UTF8.GetString(responseBytes);

  return response
   .Split('&')
   .Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
   .Split('=')[1];
 }
 catch (WebException wex)
 {
  string value = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
  throw;
 }
}  

Para obtener información sobre cómo desempaquetar la respuesta de ACS y enviarla a su aplicación o servicio web, consulte Desempaquetar y enviar el token a una aplicación o servicio web.

Para habilitar la compatibilidad con versiones anteriores con el comportamiento de solicitud de token de ACS 1.0, ACS admite la posibilidad de afirmar notificaciones como parte de las solicitudes de token.

La manera recomendada de hacerlo es registrar la aplicación o servicio de confirmación como proveedor de identidad ACS. A continuación, la aplicación o servicio solicita un token de ACS mediante la presentación de un token de SAML o SWT que contiene las notificaciones que desea confirmar y este token se firma mediante una clave de proveedor de identidad almacenada en ACS. Por ejemplo, puede enviar una solicitud de token de SAML con notificaciones confirmadas a ACS a través del protocolo OAuth WRAP de AD FS 2.0 o cualquier servicio de token de seguridad (STS) que se crea mediante Windows Identity Foundation (WIF) y se registra en ACS como proveedor de identidades de WS-Federation.

Puede usar el Portal de administración de ACS para registrar un proveedor de identidad mediante metadatos de WS-Federation, o bien puede usar el Servicio de administración de ACS para establecer individualmente las propiedades del proveedor de identidad, las direcciones y claves. (Por ejemplo, vea Procedimiento: Uso del servicio de administración de ACS para configurar AD FS 2.0 como proveedor de identidades de OpenID.) No es necesaria ninguna identidad de servicio en este método de afirmación de notificaciones en una solicitud de token. Este método es funcional a través de todos los protocolos compatibles con ACS.

Si la solicitud de token se autentica correctamente, ACS devuelve dos parámetros codificados para formulario: wrap_token y wrap_token_expires_in. Los valores de estos parámetros son el token de SWT real que el cliente puede usar para tener acceso a la aplicación web o servicio y la duración restante aproximada del token (en segundos), respectivamente.

Antes de enviar el token de SWT para la aplicación web o servicio, el cliente debe extraer y descodificar la URL desde la respuesta ACS. Si la aplicación web o servicio requiere que el token se presente en el encabezado Authorization de HTTP, el token debe ir precedido por el esquema WRAPv0.9.

En el ejemplo de código siguiente se muestra cómo desempaquetar un token y el formato del encabezado Authorization.

WebClient client = new WebClient();
client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", "mysncustomer1");
values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
values.Add("wrap_scope", "http://mysnservice.com/services");

// WebClient takes care of the URL Encoding
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

// the raw response from ACS
string response = Encoding.UTF8.GetString(responseBytes);

string token = response
    .Split('&')
    .Single(value => value.StartsWith("wrap_token=", StringComparison.OrdinalIgnoreCase))
    .Split('=')[1];

string.Format("WRAP access_token=\"{0}\"", HttpUtility.UrlDecode(token));

ACS devuelve errores cuando no puede satisfacer una solicitud de token. De acuerdo con el diseño REST, el error contiene un código de respuesta HTTP. En muchos casos, los errores de ACS también contienen SubCode y Detail que proporcionan el contexto sobre el error. El formato del error es: Error:Code:<httpStatus>:Sub-Code:<code>:Detail:<message>. El Content-Type de un error siempre es texto sin formato.

HTTP/1.1 401 Access Forbidden
Content-Type: text/plain; charset=us-ascii

Error:Code:401:SubCode:T0:Detail:ACS50009: SWT token is invalid. :TraceID:<trace id value>:TimeStamp:<timestamp value>

Para obtener más información sobre los códigos de error de ACS, vea Códigos de error de ACS.

Al depurar o recuperarse de un error devuelto desde ACS, a menudo es necesario leer el cuerpo de respuesta. En el ejemplo de código siguiente se muestra cómo leer el mensaje de error de un objeto WebException.

try
{
    WebClient client = new WebClient();
    client.BaseAddress = string.Format("https://mysnservice.accesscontrol.windows.net");

    NameValueCollection values = new NameValueCollection();
    values.Add("wrap_name", "mysncustomer1");
    values.Add("wrap_password", "5znwNTZDYC39dqhFOTDtnaikd1hiuRa4XaAj3Y9kJhQ=");
    values.Add("wrap_scope", "http://mysnservice.com/services");

    // WebClient takes care of the URL Encoding
    byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);

    // the raw response from ACS
    string response = Encoding.UTF8.GetString(responseBytes);

    string token = response
        .Split('&')
        .Single(value => value.StartsWith("wrap_access_token=",       StringComparison.OrdinalIgnoreCase))
        .Split('=')[1];
}
catch (WebException wex)
{
    if (wex.Response != null)
    {
        // the response Stream contains the error message
        StreamReader reader = new StreamReader(wex.Response.GetResponseStream());
        string message = reader.ReadToEnd();
    }
    // Throw as appropriate
}

Vea también

Mostrar: