Enkelsidig programinloggning med det implicita OAuth 2.0-flödet i Azure Active Directory B2C
Många moderna program har en spa-klientdel (ensidesapp) som främst är skriven i JavaScript. Ofta skrivs appen med hjälp av ett ramverk som React, Angular eller Vue.js. SPA:erna och andra JavaScript-appar som körs främst i en webbläsare har några ytterligare utmaningar för autentisering:
De här apparnas säkerhetsegenskaper skiljer sig från traditionella serverbaserade webbprogram.
Många auktoriseringsservrar och identitetsprovidrar stöder inte CORS-begäranden (cross-origin resource sharing).
Helsideswebbläsaren omdirigerar bort från appen kan vara invasiv för användarupplevelsen.
Det rekommenderade sättet att stödja SPA:er är OAuth 2.0-auktoriseringskodflöde (med PKCE).
Vissa ramverk, till exempel MSAL.js 1.x, stöder bara det implicita beviljandeflödet. I dessa fall stöder Azure Active Directory B2C (Azure AD B2C) implicit beviljandeflöde för OAuth 2.0-auktorisering. Flödet beskrivs i avsnitt 4.2 i OAuth 2.0-specifikationen. I implicit flöde tar appen emot token direkt från Azure AD B2C-auktorisera slutpunkt, utan server-till-server-utbyte. All autentiseringslogik och sessionshantering görs helt i JavaScript-klienten med antingen en sidomdirigering eller en popup-ruta.
Azure AD B2C utökar det implicita OAuth 2.0-standardflödet till mer än enkel autentisering och auktorisering. Azure AD B2C introducerar principparametern. Med principparametern kan du använda OAuth 2.0 för att lägga till principer i din app, till exempel användarflöden för registrering, inloggning och profilhantering. I http-exempelbegäranden i den här artikeln använder vi {tenant}.onmicrosoft.com som illustration. Ersätt {tenant}
med namnet på din klientorganisation om du har en. Du måste också ha skapat ett användarflöde.
Vi använder följande bild för att illustrera implicit inloggningsflöde. Varje steg beskrivs i detalj senare i artikeln.
Skicka autentiseringsbegäranden
När webbappen behöver autentisera användaren och köra ett användarflöde dirigeras användaren till Azure AD B2C-slutpunkten/authorize
. Användaren vidtar åtgärder beroende på användarflödet.
I den här begäran anger klienten de behörigheter som krävs för att hämta från användaren i parametern scope
och användarflödet som ska köras. Om du vill få en känsla för hur begäran fungerar kan du prova att klistra in begäran i en webbläsare och köra den. Ersätt:
{tenant}
med namnet på din Azure AD B2C-klientorganisation.90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
med app-ID:t för det program som du har registrerat i din klientorganisation.{policy}
med namnet på en princip som du har skapat i din klientorganisation, till exempelb2c_1_sign_in
.
GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=id_token+token
&redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
&response_mode=fragment
&scope=openid%20offline_access
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345
Parametrarna i HTTP GET-begäran förklaras i tabellen nedan.
Parameter | Krävs | Beskrivning |
---|---|---|
{tenant} | Yes | Namnet på din Azure AD B2C-klientorganisation |
{policy} | Yes | Namnet på det användarflöde som du vill köra. Ange namnet på ett användarflöde som du har skapat i din Azure AD B2C-klientorganisation. Till exempel: b2c_1_sign_in , b2c_1_sign_up eller b2c_1_edit_profile . |
client_id | Yes | Det program-ID som Azure Portal tilldelat till ditt program. |
response_type | Yes | Måste inkluderas id_token för OpenID Connect-inloggning. Den kan också innehålla svarstypen token . Om du använder token kan din app omedelbart ta emot en åtkomsttoken från auktoriseringsslutpunkten, utan att göra en andra begäran till auktoriseringsslutpunkten. Om du använder svarstypen token måste parametern scope innehålla ett omfång som anger vilken resurs som token ska utfärdas för. |
redirect_uri | No | Omdirigerings-URI:n för din app, där autentiseringssvar kan skickas och tas emot av din app. Den måste exakt matcha en av de omdirigerings-URI:er som du lade till i ett registrerat program i portalen, förutom att den måste vara URL-kodad. |
response_mode | No | Anger vilken metod som ska användas för att skicka tillbaka den resulterande token till din app. För implicita flöden använder du fragment . |
omfång | Yes | En blankstegsavgränsad lista över omfång. Ett enda omfångsvärde anger att Microsoft Entra ID för båda de behörigheter som begärs. Omfånget openid anger en behörighet att logga in användaren och hämta data om användaren i form av ID-token. Omfånget offline_access är valfritt för webbappar. Den anger att din app behöver en uppdateringstoken för långlivad åtkomst till resurser. |
state | No | Ett värde som ingår i begäran som också returneras i tokensvaret. Det kan vara en sträng med valfritt innehåll som du vill använda. Vanligtvis används ett slumpmässigt genererat unikt värde för att förhindra förfalskningsattacker mellan webbplatser. Tillståndet används också för att koda information om användarens tillstånd i appen innan autentiseringsbegäran inträffade, till exempel sidan som användaren var på eller användarflödet som kördes. |
Nonce | Yes | Ett värde som ingår i begäran (genereras av appen) som ingår i den resulterande ID-token som ett anspråk. Appen kan sedan verifiera det här värdet för att minimera tokenreprisattacker. Vanligtvis är värdet en slumpmässig, unik sträng som kan användas för att identifiera begärans ursprung. |
Snabb | No | Den typ av användarinteraktion som krävs. För närvarande är login det enda giltiga värdet . Den här parametern tvingar användaren att ange sina autentiseringsuppgifter för begäran. Enskilda Sign-On börjar inte gälla. |
Det här är den interaktiva delen av flödet. Användaren uppmanas att slutföra principens arbetsflöde. Användaren kan behöva ange sitt användarnamn och lösenord, logga in med en social identitet, registrera sig för ett lokalt konto eller ett annat antal steg. Användaråtgärder beror på hur användarflödet definieras.
När användaren har slutfört användarflödet returnerar Azure AD B2C ett svar till din app via redirect_uri
. Den använder metoden som anges i parametern response_mode
. Svaret är exakt detsamma för varje användaråtgärdsscenarier, oberoende av användarflödet som kördes.
Lyckat svar
Ett lyckat svar som använder response_mode=fragment
och response_type=id_token+token
ser ut så här, med radbrytningar för läsbarhet:
GET https://aadb2cplayground.azurewebsites.net/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&token_type=Bearer
&expires_in=3599
&scope="90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6 offline_access",
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=arbitrary_data_you_sent_earlier
Parameter | Beskrivning |
---|---|
access_token | Den åtkomsttoken som appen begärde från Azure AD B2C. |
token_type | Tokentypvärdet. Den enda typ som Azure AD B2C stöder är Bearer. |
expires_in | Hur lång tid åtkomsttoken är giltig (i sekunder). |
omfång | De omfång som token är giltig för. Du kan också använda omfång för att cachelagrar token för senare användning. |
id_token | Den ID-token som appen begärde. Du kan använda ID-token för att verifiera användarens identitet och starta en session med användaren. Mer information om ID-token och deras innehåll finns i referensen för Azure AD B2C-token. |
state | Om en state parameter ingår i begäran bör samma värde visas i svaret. Appen bör kontrollera att state värdena i begäran och svaret är identiska. |
Felsvar
Felsvar kan också skickas till omdirigerings-URI:n så att appen kan hantera dem på rätt sätt:
GET https://aadb2cplayground.azurewebsites.net/#
error=access_denied
&error_description=the+user+canceled+the+authentication
&state=arbitrary_data_you_can_receive_in_the_response
Parameter | Beskrivning |
---|---|
fel | En kod som används för att klassificera typer av fel som inträffar. |
error_description | Ett specifikt felmeddelande som kan hjälpa dig att identifiera rotorsaken till ett autentiseringsfel. |
state | Om en state parameter ingår i begäran bör samma värde visas i svaret. Appen bör kontrollera att state värdena i begäran och svaret är identiska. |
Verifiera ID-token
Det räcker inte att ta emot en ID-token för att autentisera användaren. Verifiera ID-tokens signatur och verifiera anspråken i token enligt appens krav. Azure AD B2C använder JSON-webbtoken (JWT) och kryptering med offentlig nyckel för att signera token och verifiera att de är giltiga.
Många bibliotek med öppen källkod är tillgängliga för validering av JWT beroende på vilket språk du föredrar att använda. Överväg att utforska tillgängliga bibliotek med öppen källkod i stället för att implementera din egen valideringslogik. Du kan använda informationen i den här artikeln för att lära dig hur du använder biblioteken på rätt sätt.
Azure AD B2C har en OpenID Connect-metadataslutpunkt. En app kan använda slutpunkten för att hämta information om Azure AD B2C vid körning. Den här informationen omfattar slutpunkter, tokeninnehåll och tokensigneringsnycklar. Det finns ett JSON-metadatadokument för varje användarflöde i din Azure AD B2C-klientorganisation. Metadatadokumentet för ett användarflöde med namnet b2c_1_sign_in
i en fabrikamb2c.onmicrosoft.com
klientorganisation finns till exempel på:
https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_sign_in/v2.0/.well-known/openid-configuration
En av egenskaperna för det här konfigurationsdokumentet jwks_uri
är . Värdet för samma användarflöde är:
https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/b2c_1_sign_in/discovery/v2.0/keys
Om du vill ta reda på vilket användarflöde som användes för att signera en ID-token (och var du hämtar metadata från) kan du använda något av följande alternativ:
Namnet på användarflödet ingår i anspråket
acr
iid_token
. Information om hur du parsar anspråken från en ID-token finns i referensen för Azure AD B2C-token.Koda användarflödet i värdet för parametern
state
när du utfärdar begäran. Avkoda sedan parameternstate
för att avgöra vilket användarflöde som användes.
När du har hämtat metadatadokumentet från OpenID Connect-metadataslutpunkten kan du använda de offentliga RSA-256-nycklarna (som finns på den här slutpunkten) för att verifiera signaturen för ID-token. Det kan finnas flera nycklar listade vid den här slutpunkten vid en viss tidpunkt, var och en identifierad av en kid
. Rubriken för id_token
innehåller också ett kid
anspråk. Det anger vilka av dessa nycklar som användes för att signera ID-token. Mer information, inklusive information om validering av token, finns i referensen för Azure AD B2C-token.
När du har verifierat signaturen för ID-token kräver flera anspråk verifiering. Exempel:
Verifiera anspråket
nonce
för att förhindra tokenreprisattacker. Värdet ska vara det du angav i inloggningsbegäran.Verifiera anspråket
aud
för att säkerställa att ID-token har utfärdats för din app. Dess värde ska vara appens program-ID.Verifiera anspråken
iat
ochexp
för att säkerställa att ID-token inte har upphört att gälla.
Flera fler verifieringar som du bör utföra beskrivs i detalj i OpenID Connect Core Spec. Du kanske också vill verifiera ytterligare anspråk, beroende på ditt scenario. Några vanliga valideringar är:
Se till att användaren eller organisationen har registrerat sig för appen.
Se till att användaren har rätt auktorisering och behörigheter.
Se till att en viss autentiseringsstyrka har inträffat, till exempel genom att använda Microsoft Entra multifaktorautentisering.
Mer information om anspråken i en ID-token finns i referensen för Azure AD B2C-token.
När du har verifierat ID-token kan du starta en session med användaren. I din app använder du anspråken i ID-token för att hämta information om användaren. Den här informationen kan användas för visning, poster, auktorisering och så vidare.
Hämta åtkomsttoken
Om det enda dina webbappar behöver göra är att köra användarflöden kan du hoppa över de kommande avsnitten. Informationen i följande avsnitt gäller endast för webbappar som behöver göra autentiserade anrop till ett webb-API som skyddas av Azure AD B2C.
Nu när du har loggat in användaren i ditt SPA kan du hämta åtkomsttoken för att anropa webb-API:er som skyddas av Microsoft Entra-ID. Även om du redan har tagit emot en token med hjälp av svarstypen kan du använda den token
här metoden för att hämta token för ytterligare resurser utan att omdirigera användaren att logga in igen.
I ett typiskt webbappflöde gör du en begäran till /token
slutpunkten. Slutpunkten stöder dock inte CORS-begäranden, så att göra AJAX-anrop för att hämta en uppdateringstoken är inte ett alternativ. I stället kan du använda det implicita flödet i ett dolt HTML iframe-element för att hämta nya token för andra webb-API:er. Här är ett exempel med radbrytningar för läsbarhet:
https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize?
client_id=90c0fe63-bcf2-44d5-8fb7-b8bbc0b29dc6
&response_type=token
&redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
&scope=https%3A%2F%2Fapi.contoso.com%2Ftasks.read
&response_mode=fragment
&state=arbitrary_data_you_can_receive_in_the_response
&nonce=12345
&prompt=none
Parameter | Obligatoriskt? | Description |
---|---|---|
{tenant} | Obligatorisk | Namnet på din Azure AD B2C-klientorganisation |
{policy} | Obligatorisk | Användarflödet som ska köras. Ange namnet på ett användarflöde som du har skapat i din Azure AD B2C-klientorganisation. Till exempel: b2c_1_sign_in , b2c_1_sign_up eller b2c_1_edit_profile . |
client_id | Obligatorisk | Program-ID:t som tilldelats din app i Azure Portal. |
response_type | Obligatorisk | Måste inkluderas id_token för inloggning med OpenID Connect. Den kan också innehålla svarstypen token . Om du använder token här kan din app omedelbart ta emot en åtkomsttoken från auktoriseringsslutpunkten, utan att göra en andra begäran till auktoriseringsslutpunkten. Om du använder svarstypen token måste parametern scope innehålla ett omfång som anger vilken resurs som token ska utfärdas för. |
redirect_uri | Rekommenderas | Omdirigerings-URI:n för din app, där autentiseringssvar kan skickas och tas emot av din app. Den måste exakt matcha en av de omdirigerings-URI:er som du registrerade i portalen, förutom att den måste vara URL-kodad. |
omfång | Obligatorisk | En blankstegsavgränsad lista över omfång. För att hämta token inkluderar du alla omfång som du behöver för den avsedda resursen. |
response_mode | Rekommenderas | Anger den metod som används för att skicka tillbaka den resulterande token till din app. Använd för implicit flöde fragment . Två andra lägen kan anges och query form_post , men fungerar inte i det implicita flödet. |
state | Rekommenderas | Ett värde som ingår i begäran som returneras i tokensvaret. Det kan vara en sträng med valfritt innehåll som du vill använda. Vanligtvis används ett slumpmässigt genererat unikt värde för att förhindra förfalskningsattacker mellan webbplatser. Tillståndet används också för att koda information om användarens tillstånd i appen innan autentiseringsbegäran inträffade. Till exempel var sidan eller vyn användaren var på. |
Nonce | Obligatorisk | Ett värde som ingår i begäran, genererat av appen som ingår i den resulterande ID-token som ett anspråk. Appen kan sedan verifiera det här värdet för att minimera tokenreprisattacker. Vanligtvis är värdet en slumpmässig, unik sträng som identifierar begärans ursprung. |
Snabb | Obligatorisk | Om du vill uppdatera och hämta token i en dold iframe använder du prompt=none för att säkerställa att iframe inte fastnar på inloggningssidan och returnerar omedelbart. |
login_hint | Obligatorisk | Om du vill uppdatera och hämta token i en dold iframe inkluderar du användarens användarnamn i det här tipset för att skilja mellan flera sessioner som användaren kan ha vid en viss tidpunkt. Du kan extrahera användarnamnet från en tidigare inloggning med hjälp av anspråket preferred_username (omfånget profile krävs för att ta emot anspråket preferred_username ). |
domain_hint | Obligatorisk | Det kan vara consumers eller organizations . Om du vill uppdatera och hämta token i en dold iframe inkluderar du domain_hint värdet i begäran. Extrahera anspråket tid från ID-token för en tidigare inloggning för att avgöra vilket värde som ska användas (omfånget profile krävs för att ta emot anspråket tid ). Om anspråksvärdet tid är 9188040d-6c67-4c5b-b112-36a304b66dad använder du domain_hint=consumers . Annars använder du domain_hint=organizations . |
Genom att ange parametern prompt=none
lyckas eller misslyckas den här begäran omedelbart och återgår till ditt program. Ett lyckat svar skickas till din app via omdirigerings-URI:n med hjälp av den metod som anges i parametern response_mode
.
Lyckat svar
Ett lyckat svar med hjälp response_mode=fragment
av ser ut så här:
GET https://aadb2cplayground.azurewebsites.net/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=arbitrary_data_you_sent_earlier
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fapi.contoso.com%2Ftasks.read
Parameter | Beskrivning |
---|---|
access_token | Den token som appen begärde. |
token_type | Tokentypen är alltid Bearer. |
state | Om en state parameter ingår i begäran bör samma värde visas i svaret. Appen bör kontrollera att state värdena i begäran och svaret är identiska. |
expires_in | Hur länge åtkomsttoken är giltig (i sekunder). |
omfång | De omfång som åtkomsttoken är giltig för. |
Felsvar
Felsvar kan också skickas till omdirigerings-URI:n så att appen kan hantera dem på rätt sätt. För prompt=none
ser ett förväntat fel ut som i det här exemplet:
GET https://aadb2cplayground.azurewebsites.net/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
Parameter | Beskrivning |
---|---|
fel | En felkodsträng som kan användas för att klassificera typer av fel som inträffar. Du kan också använda strängen för att reagera på fel. |
error_description | Ett specifikt felmeddelande som kan hjälpa dig att identifiera rotorsaken till ett autentiseringsfel. |
Om du får det här felet i iframe-begäran måste användaren logga in interaktivt igen för att hämta en ny token.
Uppdatera token
Både ID-token och åtkomsttoken upphör att gälla efter en kort tidsperiod. Din app måste vara beredd att uppdatera dessa token regelbundet. Implicita flöden tillåter inte att du hämtar en uppdateringstoken på grund av säkerhetsskäl. Om du vill uppdatera någon av tokentyperna använder du det implicita flödet i ett dolt HTML-iframe-element. I auktoriseringsbegäran inkludera parametern prompt=none
. Om du vill ta emot ett nytt id_token värde måste du använda response_type=id_token
och scope=openid
, och en nonce
parameter.
Skicka en utloggningsbegäran
När du vill logga ut användaren från appen omdirigerar du användaren till Azure AD B2C:s utloggningsslutpunkt. Du kan sedan rensa användarens session i appen. Om du inte omdirigerar användaren kanske de kan autentisera till din app igen utan att ange sina autentiseringsuppgifter igen eftersom de har en giltig session med enkel Sign-On med Azure AD B2C.
Du kan helt enkelt omdirigera användaren till end_session_endpoint
det som visas i samma OpenID Connect-metadatadokument som beskrivs i Verifiera ID-token. Exempel:
GET https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/logout?post_logout_redirect_uri=https%3A%2F%2Faadb2cplayground.azurewebsites.net%2F
Parameter | Krävs | Beskrivning |
---|---|---|
{tenant} | Yes | Namnet på din Azure AD B2C-klientorganisation. |
{policy} | Yes | Det användarflöde som du vill använda för att logga ut användaren från ditt program. Detta måste vara samma användarflöde som appen använde för att logga in användaren. |
post_logout_redirect_uri | No | Den URL som användaren ska omdirigeras till efter att utloggningen har slutförts. Om det inte ingår visar Azure AD B2C användaren ett allmänt meddelande. |
state | No | Om en state parameter ingår i begäran bör samma värde visas i svaret. Programmet bör kontrollera att state värdena i begäran och svaret är identiska. |
Anteckning
Om användaren dirigeras till rensas end_session_endpoint
en del av användarens single Sign-On-tillstånd med Azure AD B2C. Den loggar dock inte ut användaren från användarens session för social identitetsprovider. Om användaren väljer samma identitetsprovider under en efterföljande inloggning autentiseras användaren igen utan att ange sina autentiseringsuppgifter. Om en användare vill logga ut från ditt Azure AD B2C-program betyder det inte nödvändigtvis att de vill logga ut helt från sitt Facebook-konto, till exempel. För lokala konton avslutas dock användarens session korrekt.
Nästa steg
Se kodexemplet: Logga in med Azure AD B2C i ett JavaScript SPA.