Inzicht in de impliciete OAuth2-toekenningsstroom in Azure Active Directory (AD)

Waarschuwing

Deze inhoud is bedoeld voor het oudere Azure AD v1.0-eindpunt. Gebruik het Microsoft Identity Platform voor nieuwe projecten.

De impliciete OAuth2-toekenning is beroemd om de toekenning met de langste lijst met beveiligingsproblemen in de OAuth2-specificatie. En toch is dat de aanpak die wordt geïmplementeerd door ADAL JS en de methode die we adviseren bij het schrijven van BEVEILIGD-WACHTWOORDVERIFICATIE-toepassingen. Wat geeft dat? Het is allemaal een kwestie van compromissen: en zoals blijkt, is de impliciete toekenning de beste benadering die u kunt gebruiken voor toepassingen die een web-API via JavaScript gebruiken vanuit een browser.

Wat is de impliciete OAuth2-toekenning?

De typische OAuth2-autorisatiecodetoekenning is de autorisatietoekenning die gebruikmaakt van twee afzonderlijke eindpunten. Het autorisatie-eindpunt wordt gebruikt voor de gebruikersinteractiefase, wat resulteert in een autorisatiecode. Het tokeneindpunt wordt vervolgens door de client gebruikt voor het uitwisselen van de code voor een toegangstoken en vaak ook een vernieuwingstoken. Webtoepassingen moeten hun eigen toepassingsreferenties aan het tokeneindpunt presenteren, zodat de autorisatieserver de client kan verifiëren.

De impliciete OAuth2-toekenning is een variant van andere autorisatietoestemmingen. Hiermee kan een client rechtstreeks vanuit het autorisatie-eindpunt een toegangstoken verkrijgen (en id_token, wanneer u OpenId Connect gebruikt), zonder contact op te maken met het tokeneindpunt of de client te verifiëren. Deze variant is ontworpen voor op JavaScript gebaseerde toepassingen die worden uitgevoerd in een webbrowser: in de oorspronkelijke OAuth2-specificatie worden tokens geretourneerd in een URI-fragment. Hierdoor zijn de token-bits beschikbaar voor de JavaScript-code in de client, maar wordt gegarandeerd dat ze niet worden opgenomen in omleidingen naar de server. In impliciete OAuth2-toekenning geeft het autorisatie-eindpunt toegangstokens rechtstreeks aan de client uit met behulp van een omleidings-URI die eerder is opgegeven. Het heeft ook het voordeel van het elimineren van eventuele vereisten voor cross-origin-aanroepen, die nodig zijn als de JavaScript-toepassing nodig is om contact op te nemen met het tokeneindpunt.

Een belangrijk kenmerk van de impliciete OAuth2-toekenning is het feit dat dergelijke stromen nooit vernieuwingstokens retourneren aan de client. In de volgende sectie ziet u hoe dit niet nodig is en in feite een beveiligingsprobleem zou zijn.

Geschikte scenario's voor de impliciete OAuth2-toekenning

De OAuth2-specificatie verklaart dat de impliciete toekenning is ontworpen voor het inschakelen van gebruikersagenttoepassingen, zoals JavaScript-toepassingen die worden uitgevoerd in een browser. Het definiërende kenmerk van dergelijke toepassingen is dat JavaScript-code wordt gebruikt voor toegang tot serverbronnen (meestal een web-API) en voor het bijwerken van de gebruikerservaring van de toepassing dienovereenkomstig. Denk aan toepassingen zoals Gmail of Outlook Web Access: wanneer u een bericht in uw postvak in selecteert, verandert alleen het deelvenster voor de berichtweergave om de nieuwe selectie te tonen, terwijl de rest van de pagina ongewijzigd blijft. Dit kenmerk staat in contrast met traditionele web-apps die op omleidingen zijn gebaseerd, waarbij elke gebruikersactie resulteert in het opnieuw laden van de volledige pagina en een volledige weergave van het antwoord van de server.

Toepassingen die de op JavaScript gebaseerde benadering tot het uiterste gebruiken, worden toepassingen met één pagina of SPA's genoemd. Het idee is dat deze toepassingen alleen een initiële HTML-pagina en bijbehorende JavaScript dienen, waarbij alle volgende interacties worden aangestuurd door web-API-aanroepen die worden uitgevoerd via JavaScript. Hybride benaderingen, waarbij de toepassing meestal postbackgestuurd is, maar incidentele JS-aanroepen uitvoert, zijn echter niet ongewoon: de discussie over impliciet stroomgebruik is ook relevant voor die methoden.

Omleidingstoepassingen beveiligen hun aanvragen doorgaans via cookies, maar die aanpak werkt niet zo goed voor JavaScript-toepassingen. Cookies werken alleen tegen het domein waarvoor ze zijn gegenereerd, terwijl JavaScript-aanroepen naar andere domeinen mogelijk worden omgeleid. In feite is dat vaak het geval: denk aan toepassingen die Microsoft Graph API, Office API, Azure API aanroepen, allemaal buiten het domein waar de toepassing wordt geleverd. Een groeiende trend voor JavaScript-toepassingen is om helemaal geen back-end te hebben, waarbij 100% op web-API's van derden worden gebruikt om hun bedrijfsfunctie te implementeren.

Momenteel is de voorkeursmethode voor het beveiligen van aanroepen naar een web-API het gebruik van de OAuth2 Bearer-tokenbenadering, waarbij elke aanroep wordt vergezeld van een OAuth2-toegangstoken. De web-API onderzoekt het binnenkomende toegangstoken en, als het de benodigde scopes bevat, verleent het toegang tot de aangevraagde bewerking. De impliciete stroom biedt een handig mechanisme voor JavaScript-toepassingen voor het verkrijgen van toegangstokens voor een web-API, met tal van voordelen met betrekking tot cookies:

  • Tokens kunnen betrouwbaar worden verkregen zonder dat cross-origin-aanroepen nodig zijn – de verplichte registratie van de omleidings-URI waarnaar tokens worden geretourneerd, garandeert dat tokens niet worden verplaatst.
  • JavaScript-toepassingen kunnen zoveel toegangstokens verkrijgen als ze nodig hebben, voor zoveel web-API's waarop ze zijn gericht, zonder beperking voor domeinen
  • HTML5-functies zoals sessie of lokale opslag verlenen volledige controle over tokencaching en levensduurbeheer, terwijl cookiesbeheer ondoorzichtig is voor de app
  • Toegangstokens zijn niet vatbaar voor CSRF-aanvallen (Cross-Site Request Forgery)

De impliciete toekenningsstroom geeft geen vernieuwingstokens uit, meestal om veiligheidsredenen. Een refresh token is niet zo beperkt in reikwijdte als toegangstokens, waardoor het veel meer macht verleent en dus meer schade kan aanrichten als het uitlekt. In de impliciete flow worden tokens geleverd in de URL, waardoor het risico op onderschepping hoger is dan bij de autorisatiecode-verlening.

Een JavaScript-toepassing heeft echter een ander mechanisme ter beschikking voor het vernieuwen van toegangstokens zonder de gebruiker herhaaldelijk om referenties te vragen. De toepassing kan een verborgen iframe gebruiken om nieuwe tokenaanvragen uit te voeren voor het autorisatie-eindpunt van Azure AD: zolang de browser nog steeds een actieve sessie heeft (lees: heeft een sessiecookor) voor het Azure AD-domein, kan de verificatieaanvraag zonder tussenkomst van de gebruiker worden uitgevoerd.

Dit model verleent de JavaScript-toepassing de mogelijkheid om onafhankelijk toegangstokens te vernieuwen en zelfs nieuwe tokens te verkrijgen voor een nieuwe API (mits de gebruiker hiervoor eerder toestemming heeft gegeven). Dit voorkomt de extra last van het verkrijgen, onderhouden en beveiligen van een artefact met een hoge waarde, zoals een vernieuwingstoken. Het artefact dat de stille verlenging mogelijk maakt, de Cookie van de Azure AD-sessie, wordt buiten de toepassing beheerd. Een ander voordeel van deze benadering is dat een gebruiker zich kan afmelden bij Azure AD, met behulp van een van de toepassingen die zijn aangemeld bij Azure AD, die wordt uitgevoerd op een van de browsertabbladen. Dit resulteert in het verwijderen van de Azure AD-sessiecookie en de JavaScript-toepassing verliest automatisch de mogelijkheid om tokens te vernieuwen voor de afgemelde gebruiker.

Is de impliciete toekenning geschikt voor mijn app?

De impliciete autorisatie biedt meer risico's dan andere autorisaties, en de gebieden waarop u moet letten, zijn goed gedocumenteerd (bijvoorbeeld misbruik van toegangstokens om de resource-eigenaar in de impliciete flow na te bootsen en OAuth 2.0 bedreigingsmodel en beveiligingsoverwegingen). Het profiel met een hoger risico is echter grotendeels te wijten aan het feit dat het is bedoeld om toepassingen die actieve code uitvoeren in te schakelen, geleverd door een externe resource naar een browser. Als u een Single Page Application (SPA)-architectuur plant, geen backendcomponenten hebt of een web-API wilt aanroepen via JavaScript, wordt het gebruik van de impliciete stroom aanbevolen voor het verkrijgen van tokens.

Als uw toepassing een native client is, is de impliciete flow niet de beste keuze. Het ontbreken van de Azure AD-sessiecookie in de context van een systeemeigen client ontneemt uw toepassing van de middelen voor het onderhouden van een langdurige sessie. Dit betekent dat uw toepassing de gebruiker herhaaldelijk om toegang vraagt bij het verkrijgen van toegangstokens voor nieuwe bronnen.

Als u een webtoepassing ontwikkelt die een back-end bevat en een API uit de back-endcode gebruikt, is de impliciete stroom ook niet geschikt. Andere subsidies geven je veel meer macht. De toekenning van OAuth2-clientreferenties biedt bijvoorbeeld de mogelijkheid om tokens te verkrijgen die overeenkomen met de machtigingen die zijn toegewezen aan de toepassing zelf, in plaats van gebruikersdelegaties. Dit betekent dat de client de mogelijkheid heeft om programmatische toegang tot resources te behouden, zelfs wanneer een gebruiker niet actief bezig is met een sessie, enzovoort. Niet alleen dat, maar dergelijke subsidies bieden hogere veiligheidsgaranties. Toegangstokens worden bijvoorbeeld nooit doorgegeven via de browser van de gebruiker, ze lopen geen risico dat ze worden opgeslagen in de browsergeschiedenis, enzovoort. De clienttoepassing kan ook sterke verificatie uitvoeren bij het aanvragen van een token.

Volgende stappen