© Stmool/Shutterstock.com
Teil 2: Mit der MSAL eine Single Page App in Azure AD B2C integrieren

Authentication Library für JavaScript


Azure AD B2C bietet eine relativ komfortable Möglichkeit, Authentifizierung und Autorisierung zu integrieren. Aber wie geht man bei einer Single Page App konkret vor? Die Microsoft Authentication Library for JavaScript nimmt uns dabei viel Arbeit ab – legt aber auch einige Fallstricke aus.

Im letzten Artikel dieser Reihe ging es vor allem um Authentifizierungsmöglichkeiten allgemein und um Azure AD B2C im Speziellen. Wir legten im Azure Portal ein AD B2C an und registrierten sowohl eine Frontend Single Page App als auch einen Backend Service. Außerdem definierten wir Benutzer-Flows für das Anmelden und/oder Registrieren eines Benutzers und für den Passwortreset. Damit wäre alles vorbereitet, um endlich mit den eigentlichen Apps zu beginnen.

MSAL und die App-Struktur

Die Microsoft Authentication Library for JavaScript ist ein GitHub-Projekt [1], das die in Teil 1 dieser Artikelserie beschriebenen Authentifizierungsabläufe über ein JavaScript-API zur Verfügung stellt. TypeScript Typings sind dafür ebenfalls vorhanden. Wir brauchen uns daher – theoretisch – nicht mit HTTP-Aufrufen, Redirects, Pop-ups, iframes und URL-Hash-Parsing auseinanderzusetzen. MSAL liegt seit Kurzem in einer finalen Version (1.x) vor und sollte damit auch in produktiven Apps einsetzbar sein. Die Installation erfolgt z. B. über npm (falls ein Bundling-Tool wie webpack verwendet wird, das npm-require unterstützt) oder einfach über ein <script>-Tag in der HTML-Datei. Unser Beispielsystem (Abb. 1) besteht aus einem Single Page Frontend und einem Backend, die jeweils mit dem Azure AD kommunizieren. Das Frontend authentifiziert sich mittels eines Pop-up-Fensters bei AD B2C, erhält von letzterem Tokens (ID-Token, Access-Token, Details dazu später) und sendet Requests an das Backend. Mit jedem Request wird das von Azure AD erhaltene Access-Token mitgesendet. Das Backend überprüft zusammen mit dem Azure AD die Gültigkeit des Tokens und gewährt entsprechend Zugriff auf seine Ressourcen. Azure AD B2C ist in diesem Fall Identity Provider, Benutzer-DB sowie Applikations-Registry.

mahringer_azure_ADB2C_1.tif_fmt1.jpgAbb. 1: Vereinfachte Struktur der App

Aufbau unserer Single-Page, „index.html“

Um bei unserem Beispiel den Fokus auf die AD-Abläufe zu legen, verwenden wir im wahrsten Sinne des Wortes eine Single-Page, eine einzige HTML-Datei. Sie enthält das UI und den gesamten Code. Das macht es einfacher, die einzelnen Schritte aber auch die Stolpersteine herauszuarbeiten. Mit einer echten Single Page App funktioniert es ganz ähnlich, mit der Ausnahme, dass in der index.html zusätzliche JS Bundles geladen werden. Um das Request-Handling zu vereinfachen, verwenden wir in diesem Beispiel außerdem jQuery. In Listing 1 wird MSAL in unsere index.html eingebunden.

Listing 1

<html> <body style="background-color: lightblue"> <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.0/js/msal.js"> </script> <script src="https://code.jquery.com/jquery-3.2.1.min.js"> </script> <h2>Test Authentication with Azure AD B2C</h2> <div> <div id="label">Not logged in</div> <br /> <span class="blockTitle">Azure AD B2C Authentication</span> <button id="auth" onclick="login()">Login with Azure ADB2C</button> <button id="getTokenSilently" class="hidden" onclick="getTokenSilently()"> Test get token silently </button> <button id="callApiButton" class="hidden" onclick="callApi()"> Call API </button> <hr> <span class="blockTitle">Logout</span> <button id="logoutButton" class="hidden" onclick="logout()"> Logout </button> <hr> </div> <pre class="response"></pre>; ... <!-- Rest of code omitted --> </body> </html>

Zusätzlich enthält sie UI-Elemente zum Log-in, Log-out, Aufrufen des Backends, Anfordern eines Tokens und Anzeigen von Loginformationen. Abbildung 2 zeigt den Initialzustand der App vor dem Log-in.

mahringer_azure_ADB2C_2.tif_fmt1.jpgAbb. 2: Initialzustand des Frontends

MSAL-Konfiguration und erster Aufruf der „index.html“

In unserer vereinfachten App binden wir den App-Code als <script>-Tag am Ende des <body> ein. In Listing 2 konfigurieren wir zu Beginn unseren Azure-AD-B2C-Zugang. Danach kommt ein Schlüsselelement und auch gleichzeitig ein Schlüsselfallstrick: Jedes Mal, wenn unsere App annavigiert wird (entweder durch Benutzer oder durch MSAL-Authentifizierungs-Redirect-Flows), muss eine Msal.UserAgentApplication erzeugt werden. Sie übernimmt die gesamte Verarbeitung der Authentifizierungs-Flows: Pop-ups, Redirects, iframes usw. Egal welche Logik danach folgt, dieser Minimal-Stub muss immer vorhanden sein.

Listing 2

<html> <body style="background-color: lightblue"> ... <!- UI Elements --> <script> console.info(`Start script: history.length: %s`, history.length); /* Configuration   -------------------------------------------------------------------------------------------*/ const b2bScopesAuthTest = ["https://myADTenant.onmicrosoft.com/myBackendService/writeScope"]; const userFlowPolicy = "B2C_1_Test"; const clientID = "myClientAzureAdAppId"; // See Azure portal // Azure B2C config. let applicationConfig = { clientID: clientID, authority: `https://myADTenant.b2clogin.com/myADTenant.onmicrosoft.com/${userFlowPolicy}`, b2cScopes: b2bScopesAuthTest, webApi: 'http://localhost:5000/api/test', logoutApi: 'http://localhost:5000/api/logout', }; let authenticated = false; let clientApplication; let AuthStrategy = {}; AuthStrategy[AuthStrategy.PassportToken = 1] = "PassportToken"; // Not needed for sample:  // AuthStrategy[AuthStrategy.Credentials = 2] = "Credentials"; let loggedInUser = undefined;  /*  * Minumum stub necessary for Azure AD.  * Remember that MSAL will cause several redirects,   * iframes and/or popups.  * Each time the page is hit/reloaded,   * we must create an Msal.UserAgentApplication.  */ clientApplication = new Msal.UserAgentApplication( { auth: { clientId: applicationConfig.clientID, authority: ap...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang