Partager via


Demande de jeton à ACS via le protocole OAuth WRAP

S'applique à

  • Microsoft Azure Active Directory Access Control (également appelé Access Control Service ou ACS)

Vue d’ensemble

Lorsque vos applications et services web gèrent l’authentification à l’aide d’ACS, le client doit obtenir un jeton de sécurité émis par ACS pour se connecter à votre application ou service. Pour obtenir ce jeton émis par ACS (jeton de sortie), le client doit s’authentifier directement auprès d’ACS ou envoyer un jeton de sécurité émis par son fournisseur d’identité (jeton d’entrée). ACS valide ce jeton de sécurité d’entrée, traite les revendications d’identité dans ce jeton via le moteur de règles ACS, calcule les revendications d’identité de sortie et émet un jeton de sécurité de sortie.

Cette rubrique décrit les méthodes de demande d’un jeton auprès d’ACS via le protocole OAuth WRAP. Toutes les demandes de jeton via le protocole OAuth WRAP sont transmises via SSL. ACS émet toujours un jeton web simple (SWT) via le protocole OAuth WRAP, en réponse à une demande de jeton correctement mise en forme. Toutes les demandes de jeton via le protocole OAuth WRAP sont envoyées à ACS dans une requête HTTP POST. Vous pouvez demander un jeton ACS via le protocole OAuth WRAP à partir de n’importe quelle plateforme qui peut effectuer une publication HTTPS FORM POST : .NET Framework, Windows Communication Foundation (WCF), Silverlight, ASP.NET, Java, Python, Ruby, PHP, Flash et d’autres plateformes.

Le tableau suivant répertorie trois méthodes prises en charge pour demander un jeton SWT émis par ACS via le protocole OAuth WRAP.

Trois méthodes de demande de jeton à ACS via le protocole OAuth WRAP

Méthode de demande de jeton Description

Demandes de jeton de mot de passe

Cette méthode la plus simple nécessite que le client envoie un nom d’utilisateur et un mot de passe d’une identité de service directement à ACS via le protocole OAuth WRAP pour l’authentification.

Demandes de jeton SWT

Cette méthode nécessite que le client envoie un jeton SWT qui peut être signé avec une clé symétrique d’identité de service ou une clé symétrique du fournisseur d’identité à ACS via le protocole OAuth WRAP pour l’authentification.

Demandes de jeton SAML

Principalement destinée à l’intégration du service de fédération Active Directory (AD FS) 2.0, la méthode SAML (Security Assertion Markup Language) exige que le client envoie un jeton SAML signé à ACS via le protocole OAuth WRAP pour l’authentification. Cette approche permet au client d’utiliser une identité d’entreprise pour s’authentifier auprès d’ACS.

Point de terminaison émetteur de jeton

Toutes les demandes de jeton ACS via le protocole OAuth WRAP sont dirigées vers un point de terminaison d’émission de jeton ACS. L’URI de ce point de terminaison dépend de l’espace de noms Access Control. L'espace de noms se présente sous la forme d'un préfixe de nom DNS dans un URI de demande de jeton. Le reste du nom DNS est fixe, tout comme le chemin d'accès. Par exemple, si vous souhaitez demander un jeton à partir de l’espace de noms Access Control appelé « mysnservice », vous pouvez diriger une demande de jeton vers l’URI suivant : https://mysnservice.accesscontrol.windows.net/WRAPv0.9

Demandes de jeton de mot de passe

Avec une demande de jeton de mot de passe, un client peut envoyer un nom d’utilisateur et un mot de passe d’une identité de service directement à ACS via le protocole OAuth WRAP pour l’authentification. Il s’agit du moyen le plus simple de demander un jeton auprès d’ACS à l’aide du protocole OAuth WRAP. Cette approche ne nécessite aucune capacité de chiffrement autre que l'établissement d'une connexion SSL. Dans la pratique, elle est similaire au modèle de nom d'utilisateur/mot de passe qui prévaut dans les services web REST. Ce type de demande de jeton est en fait une requête HTTPS FORM POST. Les paramètres d'une demande de jeton de mot de passe sont en format codé.

Voici un exemple de transmission d'une demande en texte clair à un espace de noms nommé « 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

Le tableau ci-dessous fournit les noms, descriptions et exigences de valeur des paramètres qui doivent être présents dans une demande de jeton de mot de passe :

Nom du paramètre Description Exigences de valeur

wrap_scope

Compare la demande de jeton à un ensemble de règles. Définissez la valeur de ce paramètre sur la valeur du domaine d'application par partie de confiance. Vous pouvez obtenir cette valeur (dans le champ Domaine ) via le portail de gestion ACS en sélectionnant l’application de partie de confiance appropriée dans la page Applications de partie de confiance .

  • URI HTTP ou HTTP(s)

  • Aucun paramètre de requête ou ancre.

  • Segments de <chemin = 32.

  • Longueur maximale : 256 caractères.

  • Doit être codé URL.

wrap_name

Valide la clé du paramètre suivant. Définissez la valeur de ce paramètre sur le nom d’une identité de service dans votre espace de noms Access Control. Vous pouvez obtenir cette valeur (dans le champ Nom ) via le portail de gestion ACS en sélectionnant l’identité de service appropriée dans la page Identités de service.

  • Longueur minimale : 1 caractère.

  • Longueur maximale : 128 caractères.

  • Doit être codé URL.

wrap_password

Authentifie la demande entrante. Définissez la valeur de ce paramètre sur le mot de passe d’une identité de service dans votre espace de noms Access Control. Vous pouvez obtenir cette valeur (dans le champ Mot de passe de la page Modifier les informations d’identification ), via le portail de gestion ACS, en sélectionnant d’abord l’identité de service appropriée dans la page Identités de service, puis en sélectionnant le mot de passe approprié dans la table Informations d’identification de la page Modifier l’identité du service .

  • Chaîne d'une longueur de 1 à 64 caractères.

  • Doit être codé URL.

Les valeurs de ces paramètres doivent être encodées par URL avant d’envoyer la demande à ACS. Votre application ou service web peut fournir la valeur du wrap_scope au client, ou le client peut décider de définir la valeur du paramètre wrap_scope sur l’URI de l’application web ou de la cible de ressource de service.

Les demandes de jeton de mot de passe via le protocole OAuth WRAP peuvent également contenir des paramètres supplémentaires que ACS peut utiliser pendant le processus de calcul de revendication de sortie. Ces noms et valeurs de paramètres supplémentaires doivent être codés URL, et les valeurs ne doivent pas être mises entre guillemets.

La méthode de demande de jeton de mot de passe est assez simple.

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

Pour plus d’informations sur la façon de décompresser le jeton de sortie à partir d’ACS et de l’envoyer à l’application web ou au service, consultez Annuler la suppression et l’envoi du jeton à une application web ou à un service.

Demandes de jeton SWT

Vous pouvez également demander un jeton auprès d’ACS via le protocole OAuth WRAP à l’aide d’un jeton SWT signé par une clé symétrique. Toutes les demandes de jeton SWT sont effectuées via une requête HTTPS FORM POST. Les valeurs de paramètre de cette méthode de demande de jeton sont en format codé.

Voici un exemple de transmission d'une demande de jeton SWT adressée à l'espace de noms « 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

Une demande de jeton SWT doit présenter les paramètres et valeurs suivants :

Nom du paramètre Description Exigences de valeur

wrap_scope

Compare la demande de jeton à un ensemble de règles.

  • Définissez la valeur de ce paramètre sur la valeur du domaine d'application par partie de confiance. Vous pouvez obtenir cette valeur (dans le champ Domaine ) via le portail de gestion ACS en sélectionnant l’application de partie de confiance appropriée dans la page Applications de partie de confiance .

  • URI HTTP ou HTTP(s).

  • Aucun paramètre de requête ou ancre.

  • Segments de <chemin = 32.

  • Longueur maximale : 256 caractères.

  • Doit être codé URL.

wrap_assertion

Il s’agit du jeton d’entrée envoyé à ACS.

  • Jeton SWT signé avec des revendications d'entrée qui incluent l'émetteur et des paramètres HMACSHA256.

  • Longueur maximale : 2 048 caractères.

  • Doit être codé URL.

wrap_assertion_format

Il s’agit du format du jeton d’entrée envoyé à ACS.

SWT

Comme indiqué dans l'exemple suivant, le code requis pour effectuer une demande de jeton SWT ressemble au code requis pour effectuer une demande de jeton de mot de passe.

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

Pour plus d’informations sur la façon de décompresser la réponse d’ACS et de l’envoyer à votre application ou service web, consultez Annuler la suppression et l’envoi du jeton à une application web ou à un service.

Création d'un jeton SWT

Un jeton SWT est un ensemble de paires clé-valeur signées avec une clé de l'émetteur (clé symétrique). Un jeton SWT envoyé à ACS dans une demande de jeton SWT doit contenir les paramètres Émetteur et HMACSHA256 , ainsi que des paramètres supplémentaires, par exemple , ExpiresOn, Audience et autres revendications spécifiques au client. Le tableau suivant répertorie les noms et les descriptions des paramètres de jeton SWT :

Nom du paramètre Description

Émetteur

Dans ACS, recherche la clé utilisée pour signer le jeton. Si la signature est valide, cette valeur est utilisée pour effectuer le calcul de revendication de sortie.

Vous pouvez définir ce paramètre sur la valeur du domaine d’un fournisseur d’identité dans votre espace de noms Access Control ou le nom d’une identité de service au sein de votre espace de noms Access Control. Vous pouvez obtenir cette valeur (dans le champ Domaine sur la page Modifier le fournisseur d’identité ) via le portail de gestion ACS, en sélectionnant le fournisseur d’identité approprié sur la page Fournisseurs d’identité. Vous pouvez également obtenir cette valeur via le service de gestion ACS : il s’agit de la propriété de nom de l’enregistrement « Émetteur » créé pour chaque fournisseur d’identité.

HMACSHA256

Dans ACS, valide la signature SWT et recherche la clé d’émetteur nommée dans le paramètre Émetteur .

La signature SWT est créée à l’aide de la clé de signature symétrique attachée à une identité de service ou à un fournisseur d’identité au sein de votre espace de noms Access Control.

Public ciblé

S’il est présent, ACS utilise cette valeur pour vous assurer que ACS est la cible prévue du jeton SWT. Il s’agit de l’URL de votre espace de noms Access Control, par exemple,https://contoso.accesscontrol.windows.net/

ExpiresOn

Le cas échéant (dans le temps Epoch), indique si le jeton a expiré. Par exemple, la valeur de ce paramètre peut être 1324300962.

Revendications supplémentaires

S’il est présent, ACS utilise ces paramètres pour effectuer le calcul de revendication de sortie. Chaque type de revendication ne peut apparaître qu'une seule fois. Plusieurs valeurs de revendication du même type doivent être concaténées à l'aide d'une virgule (« , »). Pour plus d’informations sur l’assertion de revendications dans ACS, consultez Assertion de revendications via le protocole OAuth WRAP.

L'exemple de code suivant montre comment générer un jeton SWT à l'aide de . Il contient un type qui crée des jetons SWT comprenant les paramètres Issuer et 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;
    }
}

Demandes de jeton SAML

La méthode de requête de jeton SAML est destinée principalement à l’intégration d’AD FS 2.0 et permet au client d’utiliser une identité d’entreprise (Active Directory) pour s’authentifier auprès d’ACS. Avec la méthode de demande de jeton SAML, vous pouvez envoyer un jeton SAML 1.1 signé ou un jeton SAML 2.0 émis par AD FS 2.0 (jeton d’entrée) à ACS via le protocole OAuth WRAP.

ACS utilise des règles pour calculer les revendications de sortie, les regrouper dans un jeton SWT (jeton de sortie), signer celui-ci et le renvoyer au client via le protocole OAuth WRAP.

Une demande de jeton SAML doit présenter les paramètres et valeurs suivants :

Nom du paramètre Description Exigences de valeur

wrap_scope

Compare la demande de jeton à un ensemble de règles.

  • Définissez la valeur de ce paramètre sur la valeur du domaine d'application par partie de confiance. Vous pouvez obtenir cette valeur (dans le champ Domaine ) via le portail de gestion ACS en sélectionnant l’application de partie de confiance appropriée dans la page Applications de partie de confiance.

  • URI HTTP ou HTTP(s).

  • Aucun paramètre de requête ou ancre.

  • Segments <de chemin = 32.

  • Longueur maximale : 256 caractères.

  • Doit être codé URL.

wrap_assertion

Il s’agit du jeton d’entrée envoyé à ACS.

  • Jeton signé SAML 1.1 ou 2.0 avec des revendications d'entrée. Les jetons SAML 1.1 font l'objet d'une restriction. Ils nécessitent au moins une revendication d'entrée. Cela signifie qu'un fournisseur d'identité ou une identité de service prenant en charge les revendications doivent être utilisés pour l'authentification de jeton SAML 1.1. Les jetons SAML 2.0 ne nécessitent pas de revendication d'entrée pour l'authentification par rapport à une identité de service, à part la revendication NameIdentifier implicite. Par conséquent, des jetons SAML 2.0 peuvent être utilisés pour authentifier par rapport à une identité de service normale ne prenant pas en charge les revendications.

  • Doit être codé URL.

wrap_assertion_format

Il s’agit du format du jeton d’entrée envoyé à ACS.

SAML

Voici un exemple de code requis pour effectuer une demande de jeton 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;
 }
}  

Pour plus d’informations sur la façon de décompresser la réponse à partir d’ACS et de l’envoyer à votre application web ou service, consultez Annuler lewrapping et envoyer le jeton à une application web ou un service.

Assertion de revendications via le protocole OAuth WRAP

Pour activer la compatibilité descendante avec le comportement de requête de jeton ACS 1.0, ACS prend en charge la possibilité d’affirmer des revendications dans le cadre des demandes de jeton.

Enregistrement de l'application ou du service effectuant l'assertion comme un fournisseur d'identité ACS.

La méthode recommandée pour ce faire consiste à enregistrer l'application ou le service effectuant l'assertion comme un fournisseur d'identité ACS. Ensuite, l’application ou le service demande un jeton d’ACS en présentant un jeton SAML ou SWT qui contient les revendications qu’il souhaite affirmer, et ce jeton est signé à l’aide d’une clé de fournisseur d’identité stockée dans ACS. Par exemple, vous pouvez envoyer une demande de jeton SAML avec des revendications déclarées à ACS via le protocole OAuth WRAP à partir d’AD FS 2.0 ou tout service de jeton de sécurité personnalisé (STS) créé à l’aide de Windows Identity Foundation (WIF) et inscrit dans ACS en tant que fournisseur d’identité WS-Federation.

Vous pouvez utiliser le portail de gestion ACS pour inscrire un fournisseur d’identité à l’aide de WS-Federation métadonnées, ou vous pouvez utiliser le service de gestion ACS pour définir individuellement les propriétés, les adresses et les clés du fournisseur d’identité. (Par exemple, consultez Comment : utiliser le service de gestion ACS pour configurer AD FS 2.0 en tant que fournisseur d’identité Enterprise.) Aucune identité de service n'est requise dans cette méthode d'assertion de revendications dans une demande de jeton. Cette méthode est fonctionnelle via tous les protocoles pris en charge par ACS.

Désencapsulage et envoi du jeton à un service ou à une application web

Si la demande de jeton est correctement authentifiée, ACS retourne deux paramètres codés par formulaire : wrap_token et wrap_token_expires_in. Les valeurs de ces paramètres sont respectivement le jeton SWT que le client peut utiliser pour accéder à votre application ou service web, et la durée restante approximative de ce jeton (en secondes).

Avant d’envoyer le jeton SWT à l’application web ou au service, le client doit extraire et décoder l’URL à partir de la réponse ACS. Si l'application ou le service web requièrent que le jeton soit présenté dans l'en-tête HTTP Authorization, le jeton doit être précédé par le schéma WRAPv0.9.

L'exemple de code suivant montre comment décompresser un jeton et mettre en forme l'en-tête 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));

Codes d'erreur et descriptions ACS

ACS retourne des erreurs lorsqu’il ne peut pas satisfaire une demande de jeton. Conformément à la conception REST, l'erreur contient un code de réponse HTTP. Dans de nombreux cas, les erreurs ACS contiennent également un contexte qui Detail fournit un SubCode contexte sur ce qui a échoué. Le format d’erreur est : Error:Code:<httpStatus>:Sub-Code:<code>:D etail:<message>. Le Content-Type d'une erreur est toujours texte/brut.

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>

Pour plus d’informations sur les codes d’erreur ACS, consultez Codes d’erreur ACS.

Lors du débogage ou de la récupération à partir d’une erreur retournée par ACS, il est souvent nécessaire de lire le corps de la réponse. L’exemple de code suivant montre comment lire le message d’erreur à partir d’un objet 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
}

Voir aussi

Concepts

Présentation d'ACS