Tutorial: Anmelden von Benutzern und Aufrufen der Microsoft Graph-API aus einer JavaScript-Single-Page-Webanwendung (SPA) mithilfe des Autorisierungscodeflusses

In diesem Tutorial wird eine JavaScript-SPA (Single-Page-Webanwendung) erstellt, die Benutzer anmeldet und Microsoft Graph über den Autorisierungscodeflow mit PKCE aufruft. Die von Ihnen erstellte SPA verwendet die Microsoft-Authentifizierungsbibliothek (Microsoft Authentication Library, MSAL) für JavaScript v2.0.

Dieses Tutorial umfasst folgende Punkte:

  • Ausführen des OAuth 2.0-Autorisierungscodeflusses mit PKCE
  • Anmelden von persönlichen Microsoft-Konten sowie von Geschäfts-, Schul- oder Unikonten
  • Abrufen eines Zugriffstokens
  • Aufrufen der Microsoft Graph-API oder Ihrer eigenen API, für die Zugriffstoken aus Microsoft Identity Platform abgerufen werden müssen.

MSAL.js 2.0 verbessert MSAL.js 1.0 durch Unterstützung des Autorisierungscodeflusses im Browser anstelle des impliziten Genehmigungsflusses. MSAL.js 2.0 unterstütz den impliziten Fluss NICHT.

Voraussetzungen

Funktionsweise der Tutorial-App

Diagram showing the authorization code flow in a single-page application

Die in diesem Tutorial erstellte Anwendung ermöglicht einer JavaScript-SPA das Abfragen der Microsoft Graph-API, indem Sicherheitstoken aus Microsoft Identity Platform abgerufen werden. In diesem Szenario wird nach einer Benutzeranmeldung ein Zugriffstoken angefordert und den HTTP-Anforderungen im Autorisierungsheader hinzugefügt. Tokenabruf und -verlängerung werden von der Microsoft Authentication Library für JavaScript (MSAL.js) verarbeitet.

In diesem Tutorial wird MSAL.js, das Microsoft-Authentifizierungsbibliothek für JavaScript v2.0: Browserpaket, verwendet.

Abrufen des abgeschlossenen Codebeispiels

Sie können stattdessen das fertige Beispielprojekt dieses Tutorials herunterladen, indem Sie das Repository ms-identity-javascript-v2 klonen.

git clone https://github.com/Azure-Samples/ms-identity-javascript-v2.git

Um das heruntergeladene Projekt in Ihrer lokalen Entwicklungsumgebung ausführen zu können, erstellen Sie zunächst einen Localhost-Server für Ihre Anwendung, wie in Schritt 1 unter Erstellen Ihres Projekts beschrieben. Sobald Sie fertig sind, können Sie das Codebeispiel konfigurieren, indem Sie mit dem Konfigurationsschritt fortfahren.

Wenn Sie mit dem Tutorial fortfahren und die Anwendung selbst erstellen möchten, fahren Sie mit dem nächsten Abschnitt (Erstellen Ihres Projekts) fort.

Erstellen Ihres Projekts

Sobald Sie Node.js installiert haben, erstellen Sie einen Ordner, um Ihre Anwendung zu hosten, z. B. msal-spa-tutorial.

Implementieren Sie als Nächstes einen kleinen Express-Webserver für die Bereitstellung Ihrer index.html-Datei.

  1. Wechseln Sie zunächst in Ihrem Terminal zu Ihrem Projektverzeichnis, und führen Sie dann die folgenden npm-Befehle aus:

    npm init -y
    npm install @azure/msal-browser
    npm install express
    npm install morgan
    npm install yargs
    
  2. Erstellen Sie als Nächstes eine Datei namens server.js, und fügen Sie den folgenden Code hinzu:

    const express = require('express');
    const morgan = require('morgan');
    const path = require('path');
    
    const DEFAULT_PORT = process.env.PORT || 3000;
    
    // initialize express.
    const app = express();
    
    // Initialize variables.
    let port = DEFAULT_PORT;
    
    // Configure morgan module to log all requests.
    app.use(morgan('dev'));
    
    // Setup app folders.
    app.use(express.static('app'));
    
    // Set up a route for index.html
    app.get('*', (req, res) => {
        res.sendFile(path.join(__dirname + '/index.html'));
    });
    
    // Start the server.
    app.listen(port);
    console.log(`Listening on port ${port}...`);
    

Erstellen der Benutzeroberfläche für die Single-Page-Webanwendung (SPA)

  1. Erstellen Sie einen Ordner app in Ihrem Projektverzeichnis, und erstellen Sie darin eine Datei index.html für Ihre JavaScript-Single-Page-Webanwendung. Mit dieser Datei wird eine Benutzeroberfläche implementiert, die mit dem Bootstrap 4-Framework erstellt wurde, und es werden Skriptdateien für die Konfiguration, Authentifizierung und API-Aufrufe importiert.

    Fügen Sie der Datei index.html den folgenden Code hinzu:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
      <title>Microsoft identity platform</title>
      <link rel="SHORTCUT ICON" href="./favicon.svg" type="image/x-icon">
    
       <!-- msal.min.js can be used in the place of msal.js; included msal.js to make debug easy -->
      <script src="https://alcdn.msauth.net/browser/2.30.0/js/msal-browser.js"
        integrity="sha384-o4ufwq3oKqc7IoCcR08YtZXmgOljhTggRwxP2CLbSqeXGtitAxwYaUln/05nJjit"
        crossorigin="anonymous"></script>
      
      <!-- adding Bootstrap 4 for UI components  -->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
      <link rel="SHORTCUT ICON" href="https://c.s-microsoft.com/favicon.ico?v2" type="image/x-icon">
    </head>
    
    <body>
      <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
        <a class="navbar-brand" href="/">Microsoft identity platform</a>
        <div class="btn-group ml-auto dropleft">
          <button type="button" id="SignIn" class="btn btn-secondary" onclick="signIn()">
            Sign In
          </button>
        </div>
      </nav>
      <br>
      <h5 class="card-header text-center">Vanilla JavaScript SPA calling MS Graph API with MSAL.js</h5>
      <br>
      <div class="row" style="margin:auto">
        <div id="card-div" class="col-md-3" style="display:none">
          <div class="card text-center">
            <div class="card-body">
              <h5 class="card-title" id="WelcomeMessage">Please sign-in to see your profile and read your mails</h5>
              <div id="profile-div"></div>
              <br>
              <br>
              <button class="btn btn-primary" id="seeProfile" onclick="seeProfile()">See Profile</button>
              <br>
              <br>
              <button class="btn btn-primary" id="readMail" onclick="readMail()">Read Mails</button>
            </div>
          </div>
        </div>
        <br>
        <br>
        <div class="col-md-4">
          <div class="list-group" id="list-tab" role="tablist">
          </div>
        </div>
        <div class="col-md-5">
          <div class="tab-content" id="nav-tabContent">
          </div>
        </div>
      </div>
      <br>
      <br>
    
      <!-- importing bootstrap.js and supporting js libraries -->
      <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
        integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
        crossorigin="anonymous"></script>
      <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
        integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
        crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>
    
      <!-- importing app scripts (load order is important) -->
      <script type="text/javascript" src="./authConfig.js"></script>
      <script type="text/javascript" src="./graphConfig.js"></script>
      <script type="text/javascript" src="./ui.js"></script>
    
      <!-- <script type="text/javascript" src="./authRedirect.js"></script>   -->
      <!-- uncomment the above line and comment the line below if you would like to use the redirect flow -->
      <script type="text/javascript" src="./authPopup.js"></script>
      <script type="text/javascript" src="./graph.js"></script>
    </body>
    
    </html>
    
  2. Erstellen Sie als Nächstes ebenfalls im Ordner app eine Datei mit dem Namen ui.js, und fügen Sie den folgenden Code hinzu. Diese Datei wird auf DOM-Elemente zugreifen und diese aktualisieren.

    // Select DOM elements to work with
    const welcomeDiv = document.getElementById("WelcomeMessage");
    const signInButton = document.getElementById("SignIn");
    const cardDiv = document.getElementById("card-div");
    const mailButton = document.getElementById("readMail");
    const profileButton = document.getElementById("seeProfile");
    const profileDiv = document.getElementById("profile-div");
    
    function showWelcomeMessage(username) {
        // Reconfiguring DOM elements
        cardDiv.style.display = 'initial';
        welcomeDiv.innerHTML = `Welcome ${username}`;
        signInButton.setAttribute("onclick", "signOut();");
        signInButton.setAttribute('class', "btn btn-success")
        signInButton.innerHTML = "Sign Out";
    }
    
    function updateUI(data, endpoint) {
        console.log('Graph API responded at: ' + new Date().toString());
    
        if (endpoint === graphConfig.graphMeEndpoint) {
            profileDiv.innerHTML = ''
            const title = document.createElement('p');
            title.innerHTML = "<strong>Title: </strong>" + data.jobTitle;
            const email = document.createElement('p');
            email.innerHTML = "<strong>Mail: </strong>" + data.mail;
            const phone = document.createElement('p');
            phone.innerHTML = "<strong>Phone: </strong>" + data.businessPhones[0];
            const address = document.createElement('p');
            address.innerHTML = "<strong>Location: </strong>" + data.officeLocation;
            profileDiv.appendChild(title);
            profileDiv.appendChild(email);
            profileDiv.appendChild(phone);
            profileDiv.appendChild(address);
    
        } else if (endpoint === graphConfig.graphMailEndpoint) {
            if (!data.value) {
                alert("You do not have a mailbox!")
            } else if (data.value.length < 1) {
                alert("Your mailbox is empty!")
            } else {
                const tabContent = document.getElementById("nav-tabContent");
                const tabList = document.getElementById("list-tab");
                tabList.innerHTML = ''; // clear tabList at each readMail call
    
                data.value.map((d, i) => {
                    // Keeping it simple
                    if (i < 10) {
                        const listItem = document.createElement("a");
                        listItem.setAttribute("class", "list-group-item list-group-item-action")
                        listItem.setAttribute("id", "list" + i + "list")
                        listItem.setAttribute("data-toggle", "list")
                        listItem.setAttribute("href", "#list" + i)
                        listItem.setAttribute("role", "tab")
                        listItem.setAttribute("aria-controls", i)
                        listItem.innerHTML = d.subject;
                        tabList.appendChild(listItem)
    
                        const contentItem = document.createElement("div");
                        contentItem.setAttribute("class", "tab-pane fade")
                        contentItem.setAttribute("id", "list" + i)
                        contentItem.setAttribute("role", "tabpanel")
                        contentItem.setAttribute("aria-labelledby", "list" + i + "list")
                        contentItem.innerHTML = "<strong> from: " + d.from.emailAddress.address + "</strong><br><br>" + d.bodyPreview + "...";
                        tabContent.appendChild(contentItem);
                    }
                });
            }
        }
    }
    

Anwendung registrieren

Befolgen Sie die Schritte in Single-Page-Webanwendung: App-Registrierung, um eine App-Registrierung für Ihre SPA zu erstellen.

Geben Sie im Schritt Umleitungs-URI: MSA.js 2.0 mit Auorisierungscodeflusshttp://localhost:3000 ein, den Standardort, an dem die Anwendung dieses Tutorials ausgeführt wird.

Wenn Sie einen anderen Port verwenden möchten, geben Sie http://localhost:<port> ein, wobei <port> Ihre bevorzugte TCP-Portnummer ist. Wenn Sie eine andere Portnummer als 3000 angeben, aktualisieren Sie auch server.js mit Ihrer bevorzugten Portnummer.

Konfigurieren Ihrer JavaScript-SPA

Erstellen Sie eine Datei mit dem Namen authConfig.js im Ordner app, die die Konfigurationsparameter für die Authentifizierung enthält, und fügen Sie dann den folgenden Code hinzu:

/**
 * Configuration object to be passed to MSAL instance on creation. 
 * For a full list of MSAL.js configuration parameters, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md 
 */
const msalConfig = {
    auth: {
        // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
        clientId: "Enter_the_Application_Id_Here",
        // Full directory URL, in the form of https://login.microsoftonline.com/<tenant-id>
        authority: "Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here",
        // Full redirect URL, in form of http://localhost:3000
        redirectUri: "Enter_the_Redirect_Uri_Here",
    },
    cache: {
        cacheLocation: "sessionStorage", // This configures where your cache will be stored
        storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
    },
    system: {	
        loggerOptions: {	
            loggerCallback: (level, message, containsPii) => {	
                if (containsPii) {		
                    return;		
                }		
                switch (level) {		
                    case msal.LogLevel.Error:		
                        console.error(message);		
                        return;		
                    case msal.LogLevel.Info:		
                        console.info(message);		
                        return;		
                    case msal.LogLevel.Verbose:		
                        console.debug(message);		
                        return;		
                    case msal.LogLevel.Warning:		
                        console.warn(message);		
                        return;		
                }	
            }	
        }	
    }
};

/**
 * Scopes you add here will be prompted for user consent during sign-in.
 * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
 * For more information about OIDC scopes, visit: 
 * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
 */
const loginRequest = {
    scopes: ["User.Read"]
};

/**
 * Add here the scopes to request when obtaining an access token for MS Graph API. For more information, see:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/resources-and-scopes.md
 */
const tokenRequest = {
    scopes: ["User.Read", "Mail.Read"],
    forceRefresh: false // Set this to "true" to skip a cached token and go to the server to get a new token
};

Erstellen Sie immer noch im Ordner app eine Datei namens graphConfig.js. Fügen Sie den folgenden Code hinzu, um Ihrer Anwendung die Konfigurationsparameter zum Aufrufen der Microsoft Graph-API bereitzustellen:

// Add here the endpoints for MS Graph API services you would like to use.
const graphConfig = {
    graphMeEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me",
    graphMailEndpoint: "Enter_the_Graph_Endpoint_Herev1.0/me/messages"
};

Ändern Sie die Werte im Abschnitt graphConfig, wie hier beschrieben:

  • Enter_the_Graph_Endpoint_Here ist die Instanz der Microsoft Graph-API, mit der die Anwendung kommunizieren soll.
    • Ersetzen Sie beide Vorkommen dieser Zeichenfolge für den globalen Microsoft Graph-API-Endpunkt durch https://graph.microsoft.com.
    • Informationen zu Endpunkten in nationalen Cloudbereitstellungen finden Sie in der Microsoft Graph Dokumentation unter Bereitstellungen nationaler Clouds.

Die Werte graphMeEndpoint und graphMailEndpoint in Ihrer graphConfig.js sollte ähnlich wie folgt aussehen, wenn Sie den globalen Endpunkt verwenden:

graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
graphMailEndpoint: "https://graph.microsoft.com/v1.0/me/messages"

Verwenden der Microsoft-Authentifizierungsbibliothek (Microsoft Authentication Library, MSAL) für die Benutzeranmeldung

Popup

Erstellen Sie im Ordner app eine Datei mit dem Namen authPopup.js, und fügen Sie den folgenden Authentifizierungs- und Tokenerfassungscode für das Popup der Anmeldung hinzu:

// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);

let username = "";

function selectAccount() {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */

    const currentAccounts = myMSALObj.getAllAccounts();
    if (currentAccounts.length === 0) {
        return;
    } else if (currentAccounts.length > 1) {
        // Add choose account code here
        console.warn("Multiple accounts detected.");
    } else if (currentAccounts.length === 1) {
        username = currentAccounts[0].username;
        showWelcomeMessage(username);
    }
}

function handleResponse(response) {

    /**
     * To see the full list of response object properties, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#response
     */

    if (response !== null) {
        username = response.account.username;
        showWelcomeMessage(username);
    } else {
        selectAccount();
    }
}

function signIn() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    myMSALObj.loginPopup(loginRequest)
        .then(handleResponse)
        .catch(error => {
            console.error(error);
        });
}

function signOut() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    const logoutRequest = {
        account: myMSALObj.getAccountByUsername(username),
        postLogoutRedirectUri: msalConfig.auth.redirectUri,
        mainWindowRedirectUri: msalConfig.auth.redirectUri
    };

    myMSALObj.logoutPopup(logoutRequest);
}

function getTokenPopup(request) {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */
    request.account = myMSALObj.getAccountByUsername(username);
    
    return myMSALObj.acquireTokenSilent(request)
        .catch(error => {
            console.warn("silent token acquisition fails. acquiring token using popup");
            if (error instanceof msal.InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return myMSALObj.acquireTokenPopup(request)
                    .then(tokenResponse => {
                        console.log(tokenResponse);
                        return tokenResponse;
                    }).catch(error => {
                        console.error(error);
                    });
            } else {
                console.warn(error);   
            }
    });
}

function seeProfile() {
    getTokenPopup(loginRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

function readMail() {
    getTokenPopup(tokenRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMailEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

selectAccount();

Umleiten

Erstellen Sie eine Datei mit dem Namen authRedirect.js im Ordner app, und fügen Sie den folgenden Authentifizierungs- und Tokenerfassungscode für die Anmeldungsumleitung hinzu:

// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);

let username = "";

/**
 * A promise handler needs to be registered for handling the
 * response returned from redirect flow. For more information, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/acquire-token.md
 */
myMSALObj.handleRedirectPromise()
    .then(handleResponse)
    .catch((error) => {
        console.error(error);
    });

function selectAccount () {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */

    const currentAccounts = myMSALObj.getAllAccounts();

    if (currentAccounts.length === 0) {
        return;
    } else if (currentAccounts.length > 1) {
        // Add your account choosing logic here
        console.warn("Multiple accounts detected.");
    } else if (currentAccounts.length === 1) {
        username = currentAccounts[0].username;
        showWelcomeMessage(username);
    }
}

function handleResponse(response) {
    if (response !== null) {
        username = response.account.username;
        showWelcomeMessage(username);
    } else {
        selectAccount();
    }
}

function signIn() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    myMSALObj.loginRedirect(loginRequest);
}

function signOut() {

    /**
     * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    const logoutRequest = {
        account: myMSALObj.getAccountByUsername(username),
        postLogoutRedirectUri: msalConfig.auth.redirectUri,
    };

    myMSALObj.logoutRedirect(logoutRequest);
}

function getTokenRedirect(request) {
    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */
    request.account = myMSALObj.getAccountByUsername(username);

    return myMSALObj.acquireTokenSilent(request)
        .catch(error => {
            console.warn("silent token acquisition fails. acquiring token using redirect");
            if (error instanceof msal.InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return myMSALObj.acquireTokenRedirect(request);
            } else {
                console.warn(error);   
            }
        });
}

function seeProfile() {
    getTokenRedirect(loginRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMeEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

function readMail() {
    getTokenRedirect(tokenRequest)
        .then(response => {
            callMSGraph(graphConfig.graphMailEndpoint, response.accessToken, updateUI);
        }).catch(error => {
            console.error(error);
        });
}

Funktionsweise des Codes

Wenn ein Benutzer das erste Mal die Schaltfläche Anmelden auswählt, ruft die signIn-Methode loginPopup auf, um den Benutzer anzumelden. Die loginPopup-Methode öffnet ein Popupfenster mit dem Microsoft Identity Platform-Endpunkt, um die Anmeldeinformationen des Benutzers anzufordern und zu überprüfen. Nach einer erfolgreichen Anmeldung wird von msal.js der Autorisierungcodefluss initiiert.

An diesem Punkt wird ein mit PKCE geschützter Autorisierungscode an den mit CORS geschützten Tokenendpunkt gesendet und gegen Token ausgetauscht. Ein ID-Token, Zugriffstoken und Aktualisierungstoken werden von Ihrer Anwendung empfangen und von msal.js verarbeitet, und die in den Token enthaltenen Informationen werden jeweils zwischengespeichert.

Das ID-Token enthält grundlegende Informationen zum Benutzer, z. B. dessen Anzeigenamen. Wenn Sie planen, von dem ID-Token bereitgestellte Daten zu nutzen, muss Ihr Back-End-Server dieses überprüfen, um zu garantieren, dass das Token für einen gültigen Benutzer Ihrer Anwendung ausgestellt wurde.

Das Zugriffstoken hat eine begrenzte Lebensdauer und läuft nach 24 Stunden ab. Über das Aktualisierungstoken können im Hintergrund neue Zugriffstoken bezogen werden.

Die SPA, die Sie in diesem Tutorial erstellt haben, ruft acquireTokenSilent bzw. acquireTokenPopup auf, um ein Zugriffstoken zu beziehen, das zum Abfragen von Informationen zum Benutzerprofil von der Microsoft Graph-API verwendet wird. Ein Beispiel zur Überprüfung des ID-Tokens finden Sie in der Beispielanwendung active-directory-javascript-singlepageapp-dotnet-webapi-v2 auf GitHub. In diesem Beispiel wird für die Tokenüberprüfung eine ASP.NET-Web-API verwendet.

Interaktives Abrufen eines Benutzertokens

Nach der erstmaligen Anmeldung sollte Ihr App die Benutzer nicht jedes Mal erneut zur Authentifizierung auffordern, wenn sie auf eine geschützte Ressource zugreifen müssen (d. h. ein Token anzufordern). Rufen Sie acquireTokenSilent auf, um diese Aufforderungen zur erneuten Authentifizierung zu verhindern. Es gibt aber einige Situationen, in denen Sie die Interaktion mit Microsoft Identity Platform ggf. erzwingen müssen. Beispiel:

  • Benutzer müssen ihre Anmeldeinformationen erneut eingeben, weil das Kennwort abgelaufen ist.
  • Ihre Anwendung fordert Zugriff auf eine Ressource an, und die Einwilligung des Benutzers ist erforderlich.
  • Die zweistufige Authentifizierung ist erforderlich.

Beim Aufrufen von acquireTokenPopup wird ein Popupfenster geöffnet (oder Benutzer werden über acquireTokenRedirect an Microsoft Identity Platform umgeleitet). In diesem Fenster müssen Benutzer ihre Anmeldeinformationen bestätigen, ihre Zustimmung für die erforderliche Ressource geben oder die zweistufige Authentifizierung durchführen.

Automatisches Abrufen eines Benutzertokens

Die Methode acquireTokenSilent wickelt den Bezug und die Verlängerung von Token ohne Eingreifen des Benutzers ab. Nach erstmaligem Ausführen von loginPopup (oder loginRedirect) wird normalerweise die Methode acquireTokenSilent zum Beziehen von Token verwendet, die für den Zugriff auf geschützte Ressourcen für nachfolgende Aufrufe genutzt werden. (Aufrufe zum Anfordern oder Verlängern von Token werden im Hintergrund ausgeführt.) acquireTokenSilent ist in bestimmten Fällen möglicherweise nicht erfolgreich – etwa, wenn das Kennwort des Benutzers abgelaufen ist. Ihre Anwendung kann diese Ausnahme auf zwei Arten handhaben:

  1. Durch sofortiges Aufrufen von acquireTokenPopup, um eine Aufforderung zur Benutzeranmeldung auszulösen. Dieses Muster wird in der Regel in Onlineanwendungen verwendet, in denen kein nicht authentifizierter Inhalt in der Anwendung für den Benutzer verfügbar ist. Die in diesem Leitfaden generierte Beispielanwendung verwendet dieses Muster.
  2. Durch eine visuelle Benachrichtigung mit dem Hinweis, dass eine interaktive Anmeldung erforderlich ist, damit der Benutzer den richtigen Zeitpunkt zum Anmelden auswählen oder damit die Anwendung acquireTokenSilent zu einem späteren Zeitpunkt wiederholen kann. Dieses Verfahren wird normalerweise verwendet, wenn der Benutzer andere Funktionen der Anwendung nutzen kann, ohne unterbrochen zu werden – beispielsweise, wenn in der Anwendung nicht authentifizierte Inhalte vorhanden sind. In diesem Fall kann der Benutzer entscheiden, wann er sich anmelden möchte, um auf die geschützte Ressource zuzugreifen oder die veralteten Informationen zu aktualisieren.

Hinweis

In diesem Tutorial werden standardmäßig die Methoden loginPopup und acquireTokenPopup verwendet. Wenn Sie Internet Explorer verwenden, empfiehlt es sich, die Methoden loginRedirect und acquireTokenRedirect zu verwenden, da ein bekanntes Problem mit Internet Explorer und Popupfenstern vorliegt. Ein Beispiel, wie Sie dasselbe Ergebnis erreichen können, indem Sie Umleitungsmethoden verwenden, finden Sie unter authRedirect.js auf GitHub.

Aufrufen der Microsoft Graph-API

Erstellen Sie eine Datei mit dem Namen graph.js im Ordner app, und fügen Sie den folgenden Code hinzu, der REST-Aufrufe der Microsoft Graph-API durchführt:

/** 
 * Helper function to call MS Graph API endpoint
 * using the authorization bearer token scheme
*/
function callMSGraph(endpoint, token, callback) {
    const headers = new Headers();
    const bearer = `Bearer ${token}`;

    headers.append("Authorization", bearer);

    const options = {
        method: "GET",
        headers: headers
    };

    console.log('request made to Graph API at: ' + new Date().toString());

    fetch(endpoint, options)
        .then(response => response.json())
        .then(response => callback(response, endpoint))
        .catch(error => console.log(error));
}

In der in diesem Tutorial erstellten Beispielanwendung wird die Methode callMSGraph() verwendet, um eine HTTP-Anforderung vom Typ GET für eine geschützte Ressource auszuführen, die ein Token erfordert. Der Inhalt wird anschließend an den Aufrufer zurückgegeben. Diese Methode fügt das abgerufene Token in den HTTP-Autorisierungsheader ein. In der in diesem Tutorial erstellten Beispielanwendung ist die geschützte Ressource der Endpunkt me der Microsoft Graph-API, der die Profilinformationen des angemeldeten Benutzers anzeigt.

Testen Ihrer Anwendung

Sie haben die Erstellung der Anwendung abgeschlossen und sind nun bereit, den Node.js-Webserver zu starten und die Funktionalität der App zu testen.

  1. Starten Sie den Node.js-Webserver, indem Sie den folgenden Befehl im Stammverzeichnis Ihres Projektordners ausführen:

    npm start
    
  2. Navigieren Sie in Ihrem Browser zu http://localhost:3000 oder http://localhost:<port>, wobei <port> der Port ist, an dem Ihr Webserver lauscht. Der Inhalt der Datei index.html und die Schaltfläche Anmelden sollten angezeigt werden.

Anmelden bei der Anwendung

Nachdem der Browser die Datei index.html geladen hat, klicken Sie auf Anmelden. Sie werden aufgefordert, sich mit Microsoft Identity Platform anzumelden:

Web browser displaying sign-in dialog

Wenn Sie sich zum ersten Mal bei Ihrer Anwendung anmelden, werden Sie aufgefordert, ihr Zugriff auf Ihr Profil zu gewähren und sich anzumelden:

Content dialog displayed in web browser

Wenn Sie den angeforderten Berechtigungen zustimmen, zeigt die Webanwendung Ihren Benutzernamen an, was eine erfolgreiche Anmeldung signalisiert:

Results of a successful sign-in in the web browser

Aufrufen der Graph-API

Nachdem Sie sich angemeldet haben, wählen Sie Profil anzeigen aus, um die Benutzerprofilinformationen anzuzeigen, die in der Antwort des Aufrufs der Microsoft Graph-API zurückgegeben werden:

Profile information from Microsoft Graph displayed in the browser

Weitere Informationen zu Bereichen und delegierten Berechtigungen

Die Microsoft Graph-API benötigt den Bereich user.read, um das Benutzerprofil zu lesen. Dieser Bereich wird standardmäßig jeder Anwendung automatisch hinzugefügt, die im Microsoft Entra Admin Center registriert ist. Andere Microsoft Graph-APIs sowie benutzerdefinierte APIs für Ihren Back-End-Server erfordern unter Umständen zusätzliche Bereiche. Die Microsoft Graph-API benötigt beispielsweise den Bereich Mail.Read, um die E-Mail des Benutzers aufzuführen.

Wenn Sie Bereiche hinzufügen, werden Ihre Benutzer möglicherweise aufgefordert, zusätzliche Zustimmung für die hinzugefügten Bereiche zu erteilen.

Wenn eine Back-End-API keinen Bereich benötigt, was nicht empfohlen wird, können Sie clientId bei den Aufrufen zum Beschaffen von Token als Bereich verwenden.

Hilfe und Support

Wenn Sie Hilfe benötigen, ein Problem melden möchten oder sich über Ihre Supportoptionen informieren möchten, finden Sie weitere Informationen unter Hilfe und Support für Entwickler.

Nächste Schritte

  • Erfahren Sie mehr, indem Sie eine React-Single-Page-Webanwendung (Single-Page Application, SPA) erstellen, die Benutzer bei der folgenden mehrteiligen Lernprogrammreihe anmeldet.