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.

Diagram i simbaneformat som visar implicit OpenID Connect-flöde

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 exempel b2c_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_upeller 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 tokenkan 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 logindet 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 i id_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 parametern state 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 och exp 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_upeller 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 queryform_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-36a304b66dadanvä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=noneser 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.