Dela via


Förstå det implicita beviljandeflödet för OAuth2 i Azure Active Directory (AD)

Varning

Det här innehållet gäller för den äldre Azure AD v1.0-slutpunkten. Använd Microsofts identitetsplattform för nya projekt.

Det implicita OAuth2-beviljandet är ökänd för att vara beviljandet med den längsta listan över säkerhetsproblem i OAuth2-specifikationen. Och ändå är det den metod som implementeras av ADAL JS och den vi rekommenderar när du skriver SPA-program. Vad ger? Det handlar om kompromisser: och det visar sig att implicit beviljande är den bästa metoden du kan använda för program som använder ett webb-API via JavaScript från en webbläsare.

Vad är implicit OAuth2-beviljande?

Det viktigaste OAuth2-auktoriseringskoden är det beviljande av auktorisering som använder två separata slutpunkter. Auktoriseringsslutpunkten används för användarinteraktionsfasen, vilket resulterar i en auktoriseringskod. Tokenslutpunkten används sedan av klienten för att utbyta koden mot en åtkomsttoken, och ofta även en uppdateringstoken. Webbprogram måste presentera sina egna programautentiseringsuppgifter för tokenslutpunkten, så att auktoriseringsservern kan autentisera klienten.

Implicit OAuth2-beviljande är en variant av andra auktoriseringsbidrag. Det gör att en klient kan hämta en åtkomsttoken (och id_token när du använder OpenId Connect) direkt från auktoriseringsslutpunkten, utan att kontakta tokenslutpunkten eller autentisera klienten. Den här varianten har utformats för JavaScript-baserade program som körs i en webbläsare: i den ursprungliga OAuth2-specifikationen returneras token i ett URI-fragment. Det gör tokenbitarna tillgängliga för JavaScript-koden i klienten, men garanterar att de inte inkluderas i omdirigeringar mot servern. I implicit OAuth2-beviljande utfärdar auktoriseringsslutpunkten åtkomsttoken direkt till klienten med hjälp av en omdirigerings-URI som angavs tidigare. Det har också fördelen att eliminera eventuella krav för korsande anrop, vilket är nödvändigt om JavaScript-programmet krävs för att kontakta tokenslutpunkten.

En viktig egenskap hos det implicita OAuth2-beviljandet är det faktum att sådana flöden aldrig returnerar uppdateringstoken till klienten. Nästa avsnitt visar hur detta inte är nödvändigt och i själva verket skulle vara ett säkerhetsproblem.

Lämpliga scenarier för implicit beviljande av OAuth2

OAuth2-specifikationen deklarerar att det implicita beviljandet har utformats för att aktivera användaragentprogram – det vill säga JavaScript-program som körs i en webbläsare. Den definierande egenskapen för sådana program är att JavaScript-kod används för åtkomst till serverresurser (vanligtvis ett webb-API) och för att uppdatera programanvändarupplevelsen i enlighet med detta. Tänk på program som Gmail eller Outlook Web Access: när du väljer ett meddelande i inkorgen ändras bara panelen för meddelandevisualisering så att den nya markeringen visas, medan resten av sidan förblir oförändrad. Den här egenskapen skiljer sig från traditionella omdirigeringsbaserade webbappar, där varje användarinteraktion resulterar i en fullständig sidåterställning och en fullständig sidåtergivning av det nya serversvaret.

Program som använder den JavaScript-baserade metoden till sin extremitet kallas enkelsidiga program eller SPA: ar. Tanken är att dessa program endast hanterar en första HTML-sida och tillhörande JavaScript, där alla efterföljande interaktioner drivs av webb-API-anrop som utförs via JavaScript. Hybridmetoder, där programmet främst är postback-drivna men utför tillfälliga JS-anrop, är dock inte ovanliga – diskussionen om implicit flödesanvändning är relevant även för dem.

Omdirigeringsbaserade program skyddar vanligtvis sina begäranden via cookies, men den metoden fungerar inte lika bra för JavaScript-program. Cookies fungerar bara mot den domän som de har genererats för, medan JavaScript-anrop kan riktas mot andra domäner. I själva verket är det ofta så: tänk på program som anropar Microsoft Graph API, Office API, Azure API – alla finns utanför domänen där programmet hanteras. En växande trend för JavaScript-program är att inte ha någon serverdel alls, med 100 % på webb-API:er från tredje part för att implementera sin affärsfunktion.

Den bästa metoden för att skydda anrop till ett webb-API är för närvarande att använda metoden för OAuth2-ägartoken, där varje anrop åtföljs av en OAuth2-åtkomsttoken. Webb-API:et undersöker den inkommande åtkomsttoken och ger åtkomst till den begärda åtgärden om den hittar de nödvändiga omfången i den. Det implicita flödet ger en praktisk mekanism för JavaScript-program för att hämta åtkomsttoken för ett webb-API, vilket ger många fördelar när det gäller cookies:

  • Token kan erhållas på ett tillförlitligt sätt utan behov av kors origin-anrop – obligatorisk registrering av omdirigerings-URI som token är returgarantier för att token inte förskjuts
  • JavaScript-program kan hämta så många åtkomsttoken som de behöver för så många webb-API:er de riktar in sig på – utan begränsning på domäner
  • HTML5-funktioner som session eller lokal lagring ger fullständig kontroll över tokencachelagring och livslängdshantering, medan cookieshantering är ogenomskinlig för appen
  • Åtkomsttoken är inte mottagliga för csrf-attacker (cross-site request forgery)

Det implicita beviljandeflödet utfärdar inte uppdateringstoken, främst av säkerhetsskäl. En uppdateringstoken är inte lika begränsad som åtkomsttoken, vilket ger mycket mer kraft och orsakar därmed mycket mer skada om den läcker ut. I det implicita flödet levereras token i URL:en, vilket innebär att risken för avlyssning är högre än i beviljandet av auktoriseringskod.

Ett JavaScript-program har dock en annan mekanism till sitt förfogande för att förnya åtkomsttoken utan att upprepade gånger fråga användaren om autentiseringsuppgifter. Programmet kan använda en dold iframe för att utföra nya tokenbegäranden mot auktoriseringsslutpunkten för Azure AD: så länge webbläsaren fortfarande har en aktiv session (läs: har en sessionscookie) mot den Azure AD domänen kan autentiseringsbegäran utföras utan behov av användarinteraktion.

Den här modellen ger JavaScript-programmet möjlighet att oberoende förnya åtkomsttoken och till och med skaffa nya för ett nytt API (förutsatt att användaren tidigare samtyckt till dem). På så sätt undviker du den extra bördan att hämta, underhålla och skydda en artefakt med högt värde, till exempel en uppdateringstoken. Artefakten som gör tyst förnyelse möjlig, Azure AD sessionscookie, hanteras utanför programmet. En annan fördel med den här metoden är att en användare kan logga ut från Azure AD, med något av de program som är inloggade på Azure AD, som körs på någon av webbläsarflikarna. Detta resulterar i borttagningen av Azure AD sessionscookie, och JavaScript-programmet förlorar automatiskt möjligheten att förnya token för den utloggade användaren.

Är det implicita beviljandet lämpligt för min app?

Det implicita beviljandet medför fler risker än andra bidrag, och de områden som du måste vara uppmärksam på är väldokumenterade (till exempel missbruk av åtkomsttoken för att personifiera resursägare i implicit flöde och OAuth 2.0 Hotmodell och säkerhetsöverväganden). Den högre riskprofilen beror dock till stor del på att den är avsedd att aktivera program som kör aktiv kod, som hanteras av en fjärrresurs till en webbläsare. Om du planerar en SPA-arkitektur, inte har några serverdelskomponenter eller planerar att anropa ett webb-API via JavaScript rekommenderar vi att du använder det implicita flödet för tokenförvärv.

Om ditt program är en intern klient passar inte det implicita flödet bra. Avsaknaden av Azure AD sessionscookie i samband med en intern klient berövar ditt program från att upprätthålla en långlivad session. Det innebär att ditt program upprepade gånger uppmanar användaren när de hämtar åtkomsttoken för nya resurser.

Om du utvecklar ett webbprogram som innehåller en serverdel och använder ett API från dess serverdelskod passar inte det implicita flödet. Andra bidrag ger dig mycket mer makt. Till exempel ger beviljandet av OAuth2-klientautentiseringsuppgifter möjligheten att hämta token som återspeglar de behörigheter som tilldelats själva programmet, i stället för användardelegeringar. Det innebär att klienten har möjlighet att upprätthålla programmatisk åtkomst till resurser även när en användare inte är aktivt engagerad i en session och så vidare. Inte bara det, utan sådana bidrag ger högre säkerhetsgarantier. Åtkomsttoken överförs till exempel aldrig via användarens webbläsare, de riskerar inte att sparas i webbläsarhistoriken och så vidare. Klientprogrammet kan också utföra stark autentisering när en token begärs.

Nästa steg