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 . |
|
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. |
|
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 . |
|
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. |
|
wrap_assertion |
Il s’agit du jeton d’entrée envoyé à ACS. |
|
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 |
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. |
|
wrap_assertion |
Il s’agit du jeton d’entrée envoyé à ACS. |
|
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
}