Anvisningar: Begära en token från ACS via OAuth WRAP Protocol
Gäller för
- Microsoft Azure Active Directory Access Control (kallas även Access Control Service eller ACS)
Översikt
När dina webbprogram och tjänster hanterar autentisering med HJÄLP av ACS måste klienten hämta en säkerhetstoken som utfärdats av ACS för att logga in på ditt program eller din tjänst. För att kunna hämta denna ACS-utfärdade token (utdatatoken) måste klienten antingen autentisera direkt med ACS eller skicka en säkerhetstoken som utfärdats av dess identitetsprovider (indatatoken). ACS validerar denna indatasäkerhetstoken, bearbetar identitetsanspråken i denna token via ACS-regelmotorn, beräknar utdataidentitetsanspråken och utfärdar en utdatasäkerhetstoken.
I det här avsnittet beskrivs metoderna för att begära en token från ACS via OAuth WRAP-protokollet. Alla tokenbegäranden via OAuth WRAP-protokollet överförs via SSL. ACS utfärdar alltid en enkel webbtoken (SWT) via OAuth WRAP-protokollet som svar på en korrekt formaterad tokenbegäran. Alla tokenbegäranden via OAuth WRAP-protokollet skickas till ACS i en HTTP POST. Du kan begära en ACS-token via OAuth WRAP-protokollet från valfri plattform som kan göra en HTTPS FORM POST: .NET Framework, Windows Communication Foundation (WCF), Silverlight, ASP.NET, Java, Python, Ruby, PHP, Flash och andra plattformar.
I följande tabell visas tre metoder som stöds för att begära en ACS-utfärdad SWT-token via OAuth WRAP-protokollet.
Tre metoder för att begära en token från ACS via OAuth WRAP-protokollet
Metod för tokenbegäran | Description |
---|---|
Begäranden om lösenordstoken |
Den här enklaste metoden kräver att klienten skickar ett användarnamn och lösenord från en tjänstidentitet direkt till ACS via OAuth WRAP-protokollet för autentisering. |
SWT-tokenbegäranden |
Den här metoden kräver att klienten skickar en SWT-token som kan signeras med en symmetrisk nyckel för tjänstidentitet eller en symmetrisk nyckel för identitetsprovidern till ACS via OAuth WRAP-protokollet för autentisering. |
SAML-tokenbegäranden |
Metoden Security Assertion Markup Language (SAML) är främst avsedd för Active Directory Federation Service (AD FS) 2.0-integrering och kräver att klienten skickar en signerad SAML-token till ACS via OAuth WRAP-protokollet för autentisering. Med den här metoden kan klienten använda en företagsidentitet för att autentisera med ACS. |
Tokenutfärdande slutpunkt
Alla ACS-tokenbegäranden via OAuth WRAP-protokollet riktas mot en ACS-tokenutfärdande slutpunkt. URI:n för den här slutpunkten beror på Access Control namnområdet. Namnområdet visas som ett DNS-namnprefix i en URI för tokenbegäran. Resten av DNS-namnet är fast, liksom sökvägen. Om du till exempel vill begära en token från Access Control namnrymd med namnet "mysnservice" kan du dirigera en tokenbegäran till följande URI: https://mysnservice.accesscontrol.windows.net/WRAPv0.9.
Begäranden om lösenordstoken
Med en begäran om lösenordstoken kan en klient skicka ett användarnamn och lösenord från en tjänstidentitet direkt till ACS via OAuth WRAP-protokollet för autentisering. Det här är det enklaste sättet att begära en token från ACS med hjälp av OAuth WRAP-protokollet. Förutom att upprätta en SSL-anslutning kräver den här metoden ingen kryptografisk funktion. I praktiken liknar det den användarnamn/lösenordsmodell som är vanligt förekommande i REST-webbtjänster. Den här typen av tokenbegäran är i praktiken ett HTTPS-formulär POST. Parametrarna i en begäran om lösenordstoken är formulärkodade.
Följande är ett exempel på en trådspårning av en klartextbegäran till ett namnområde med namnet "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
Tabellen nedan innehåller namn, beskrivningar och värdekrav för de parametrar som krävs för att finnas i en begäran om lösenordstoken:
Parameternamn | Beskrivning | Värdekrav |
---|---|---|
wrap_scope |
Matchar tokenbegäran mot en uppsättning regler. Ange värdet för den här parametern till värdet för den förlitande partens programsfär. Du kan hämta det här värdet (i fältet Sfär ) via ACS-hanteringsportalen genom att välja rätt förlitande part-program på sidan Program för förlitande part . |
|
wrap_name |
Verifierar nyckeln för nästa parameter. Ange värdet för den här parametern till namnet på en tjänstidentitet i ditt Access Control namnområde. Du kan hämta det här värdet (i fältet Namn ) via ACS-hanteringsportalen genom att välja lämplig tjänstidentitet på sidan Tjänstidentiteter . |
|
wrap_password |
Autentiserar den inkommande begäran. Ange värdet för den här parametern till lösenordet för en tjänstidentitet i ditt Access Control namnområde. Du kan hämta det här värdet (i fältet Lösenord på sidan Redigera autentiseringsuppgifter ) via ACS-hanteringsportalen genom att först välja lämplig tjänstidentitet på sidan Tjänstidentiteter och sedan välja lämpligt lösenord i tabellen Autentiseringsuppgifter på sidan Redigera tjänstidentitet . |
|
Värdena för dessa parametrar måste vara URL-kodade innan du skickar begäran till ACS. Din webbapp eller tjänst kan ange värdet för wrap_scope till klienten, eller så kan klienten välja att ange värdet för parametern wrap_scope till URI:n för webbprogrammet eller tjänstresursmålet.
Begäranden om lösenordstoken via OAuth WRAP-protokollet kan också innehålla ytterligare parametrar som ACS kan använda under beräkningsprocessen för utdataanspråk. Dessa ytterligare parameternamn och värden måste vara URL-kodade och värden får inte anges.
Metoden för begäran om lösenordstoken är ganska enkel med hjälp av .
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);
Information om hur du packar upp utdatatoken från ACS och skickar den till webbappen eller -tjänsten finns i Unwrapping and sending the token to a web application or service (Ta bort och skicka token till ett webbprogram eller en webbtjänst).
SWT-tokenbegäranden
Du kan också begära en token från ACS via OAuth WRAP-protokollet med hjälp av en SWT-token som signerats av en symmetrisk nyckel. Alla SWT-tokenbegäranden görs via ett HTTPS-formulär POST. Parametervärdena i den här metoden för tokenbegäran är formulärkodade.
Följande är ett exempel på en trådspårning av en SWT-tokenbegäran till namnområdet "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
En SWT-tokenbegäran måste ha följande parametrar och värden:
Parameternamn | Beskrivning | Värdekrav |
---|---|---|
wrap_scope |
Matchar tokenbegäran mot en uppsättning regler. |
|
wrap_assertion |
Det här är den indatatoken som skickas till ACS. |
|
wrap_assertion_format |
Det här är formatet för den indatatoken som skickas till ACS. |
SWT |
Som du ser i följande exempel liknar koden som krävs för att göra en SWT-tokenbegäran den kod som krävs för att göra en begäran om lösenordstoken.
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);
Information om hur du packar upp svaret från ACS och skickar det till ditt webbprogram eller din webbtjänst finns i Unwrapping and sending the token to a web application or service (Ta bort och skicka token till ett webbprogram eller en webbtjänst).
Skapa en SWT-token
En SWT-token är en uppsättning nyckel/värde-par som signeras med en utfärdarnyckel (en symmetrisk nyckel). En SWT-token som skickas till ACS i en SWT-tokenbegäran måste innehålla parametrarna Issuer och HMACSHA256 samt ytterligare parametrar, till exempel ExpiresOn, Audience och andra klientspecifika anspråk. Följande tabell innehåller namn och beskrivningar av SWT-tokenparametrar:
Parameternamn | Beskrivning |
---|---|
Emittenten |
I ACS letar du upp nyckeln som användes för att signera token. Om signaturen är giltig används det här värdet för att utföra utgående anspråksberäkning. Du kan ange den här parametern till värdet för sfären för en identitetsprovider i ditt Access Control-namnområde eller namnet på en tjänstidentitet i ditt Access Control namnområde. Du kan hämta det här värdet (i fältet Sfär på sidan Redigera identitetsprovider ) via ACS-hanteringsportalen genom att välja lämplig identitetsprovider på sidan Identitetsprovidrar. Eller så kan du hämta det här värdet via ACS-hanteringstjänsten – det här är namnegenskapen för den "Utfärdare"-post som skapas för varje identitetsprovider. |
HMACSHA256 |
I ACS validerar swt-signaturen och letar upp utfärdarnyckeln med namnet i parametern Issuer . SWT-signaturen skapas med hjälp av den symmetriska signeringsnyckeln som är kopplad till en tjänstidentitet eller en identitetsprovider i ditt Access Control namnområde. |
Målgrupp |
Om det finns använder ACS det här värdet för att se till att ACS är det avsedda målet för SWT-token. Det här är URL:en för ditt Access Control namnområde, till exempelhttps://contoso.accesscontrol.windows.net/ |
ExpiresOn |
Om det finns (i epoktid) anger om token har upphört att gälla. Värdet för den här parametern kan till exempel vara |
Ytterligare anspråk |
Om det finns använder ACS dessa parametrar för att utföra utdataanspråksberäkning. Varje anspråkstyp får bara visas en gång. Flera anspråksvärden av samma anspråkstyp måste sammanfogas tillsammans med ett "," (kommatecken). Mer information om hur du gör anspråk i ACS finns i Anspråksförsäkran via OAuth WRAP-protokollet. |
Följande kodexempel visar hur du genererar en SWT-token med hjälp av . Den innehåller en typ som skapar SWT-token som innehåller parametrarna Issuer och 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;
}
}
SAML-tokenbegäranden
Metoden för SAML-tokenbegäran är främst avsedd för AD FS 2.0-integrering och gör att klienten kan använda en företagsidentitet (Active Directory) för att autentisera med ACS. Med metoden för SAML-tokenbegäran kan du skicka en signerad SAML 1.1 eller en SAML 2.0-token som utfärdats av AD FS 2.0 (indatatoken) till ACS via OAuth WRAP-protokollet.
ACS använder sina regler för att beräkna utdataanspråken, gruppera dem i en SWT-token (utdatatoken), signerar den och returnerar den till klienten via OAuth WRAP-protokollet.
En SAML-tokenbegäran måste ha följande parametrar och värden:
Parameternamn | Beskrivning | Värdekrav |
---|---|---|
wrap_scope |
Matchar tokenbegäran mot en uppsättning regler. |
|
wrap_assertion |
Det här är den indatatoken som skickas till ACS. |
|
wrap_assertion_format |
Det här är formatet för den indatatoken som skickas till ACS. |
SAML |
Följande är ett exempel på den kod som krävs för att göra en SAML-tokenbegäran.
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;
}
}
Information om hur du packar upp svaret från ACS och skickar det till ditt webbprogram eller din webbtjänst finns i Unwrapping and sending the token to a web application or service (Ta bort och skicka token till ett webbprogram eller en webbtjänst).
Anspråkspåstående via OAuth WRAP-protokollet
För att möjliggöra bakåtkompatibilitet med ACS 1.0-tokenbegäran har ACS stöd för möjligheten att kontrollera anspråk som en del av tokenbegäranden.
Registrera det kontrollprogram eller den tjänst som en ACS-identitetsprovider.
Det rekommenderade sättet att göra detta är att registrera det kontrollerande programmet eller tjänsten som en ACS-identitetsprovider. Sedan begär programmet eller tjänsten en token från ACS genom att presentera en SAML- eller SWT-token som innehåller de anspråk som den vill kontrollera, och denna token signeras med hjälp av en identitetsprovidernyckel som lagras i ACS. Du kan till exempel skicka en SAML-tokenbegäran med anspråk till ACS via OAuth WRAP-protokollet från AD FS 2.0 eller en anpassad säkerhetstokentjänst (STS) som har skapats med Windows Identity Foundation (WIF) och registrerats i ACS som en WS-Federation identitetsprovider.
Du kan använda ACS-hanteringsportalen för att registrera en identitetsprovider med hjälp av WS-Federation metadata, eller så kan du använda ACS-hanteringstjänsten för att individuellt ange egenskaper, adresser och nycklar för identitetsprovidern. (Se till exempel Så här: Använd ACS-hanteringstjänsten för att konfigurera AD FS 2.0 som en företagsidentitetsprovider.) Inga tjänstidentiteter krävs i den här metoden för att göra anspråk i en tokenbegäran. Den här metoden fungerar via alla protokoll som stöds av ACS.
Ta bort och skicka token till ett webbprogram eller en tjänst
Om tokenbegäran har autentiserats returnerar ACS två formulärkodade parametrar: wrap_token och wrap_token_expires_in. Värdena för dessa parametrar är den faktiska SWT-token som klienten kan använda för att få åtkomst till ditt webbprogram eller din webbtjänst och den ungefärliga återstående livslängden för denna token (i sekunder).
Innan swt-token skickas till webbprogrammet eller tjänsten måste klienten extrahera och URL-avkoda den från ACS-svaret. Om webbprogrammet eller tjänsten kräver att token visas i HTTP-huvudet Authorization
måste token föregås av schemat WRAPv0.9
.
Följande kodexempel visar hur du packar upp en token och formaterar Authorization
huvudet.
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-felkoder och beskrivningar
ACS returnerar fel när det inte kan uppfylla en tokenbegäran. I enlighet med REST-designen innehåller felet en HTTP-svarskod. I många fall innehåller ACS-fel också en SubCode
och Detail
som ger kontext om vad som misslyckades. Felformatet är: Error:Code:<httpStatus>:Sub-Code:<code>:D etail:<message>. Felet Content-Type
är alltid text/oformaterad.
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>
Mer information om ACS-felkoder finns i ACS-felkoder.
När du felsöker eller återställer från ett fel som returneras från ACS måste du ofta läsa svarstexten. Följande kodexempel visar hur du läser felmeddelandet från ett WebException-objekt .
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
}