Erstellen eines Node.js-Office-Add-Ins, das einmaliges Anmelden verwendet

Wenn ein Benutzer sich bei Office anmeldet, kann Ihr Office-Web-Add-In diesen Anmeldeprozess nutzen, um den Benutzer sowohl beim Add-In als auch bei Microsoft Graph zu autorisieren, ohne dass eine zweite Anmeldung nötig wäre. Eine Übersicht finden Sie unter Aktivieren von Single Sign-On in einem Office-Add-In.

Dieser Artikel führt Sie durch den Prozess der Aktivierung des einmaligen Anmeldens (Single Sign-On, SSO) in einem Add-In. Das von Ihnen erstellte Beispiel-Add-In umfasst zwei Teile: ein Aufgabenbereich, der in Microsoft Excel geladen wird, und ein Server der mittleren Ebene, der Aufrufe von Microsoft Graph für den Aufgabenbereich verarbeitet. Der Server der mittleren Ebene wird mit Node.js und Express erstellt und macht eine einzelne REST-API verfügbar, /getuserfilenamesdie eine Liste der ersten 10 Dateinamen im OneDrive-Ordner des Benutzers zurückgibt. Der Aufgabenbereich verwendet die getAccessToken() -Methode, um ein Zugriffstoken für den angemeldeten Benutzer auf dem Server der mittleren Ebene abzurufen. Der Server der mittleren Ebene verwendet den On-Behalf-Of-Flow (OBO), um das Zugriffstoken gegen ein neues mit Zugriff auf Microsoft Graph auszutauschen. Sie können dieses Muster erweitern, um auf beliebige Microsoft Graph-Daten zuzugreifen. Der Aufgabenbereich ruft immer eine REST-API der mittleren Ebene auf (übergibt das Zugriffstoken), wenn Microsoft Graph-Dienste benötigt werden. Die mittlere Ebene verwendet das über OBO abgerufene Token, um Microsoft Graph-Dienste aufzurufen und die Ergebnisse an den Aufgabenbereich zurückzugeben.

Dieser Artikel funktioniert mit einem Add-In, das Node.js und Express verwendet. Unter Erstellen eines ASP.NET-Add-Ins, das einmaliges Anmelden verwendet finden Sie einen ähnlichen Artikel zu ASP.NET-basierten Add-Ins.

Voraussetzungen

  • Node.js (die aktuellsteLTS Version)

  • Git Bash (oder ein anderer Git-Client)

  • Einen Code-Editor– Wir empfehlen Visual Studio Code

  • Mindestens einige Dateien und Ordner, die auf OneDrive for Business in Ihrem Microsoft 365-Abonnement gespeichert sind

  • Ein Build von Microsoft 365, der den IdentityAPI 1.3-Anforderungssatz unterstützt. Sie können sich über das Microsoft 365-Entwicklerprogramm für ein Microsoft 365 E5-Entwicklerabonnement qualifizieren, das eine Entwicklersandbox enthält. Weitere Informationen finden Sie in den häufig gestellten Fragen. Die Entwicklersandbox enthält ein Microsoft Azure-Abonnement, das Sie in späteren Schritten in diesem Artikel für App-Registrierungen verwenden können. Wenn Sie möchten, können Sie ein separates Microsoft Azure-Abonnement für App-Registrierungen verwenden. Erhalten Sie ein Testabonnement bei Microsoft Azure.

Einrichten des Startprojekts

  1. Klonen Sie das Repository unter Office-Add-in-NodeJS-SSO, oder laden Sie es herunter.

    Hinweis

    Es sind zwei Versionen des Beispiel-Add-Ins verfügbar.

    • Der Ordner "Begin " ist ein Startprojekt. Die Benutzeroberfläche sowie alle anderen Komponenten des Add-Ins, die nicht direkt mit SSO oder der Autorisierung in Zusammenhang stehen, wurden hier bereits erstellt. In späteren Abschnitten dieses Artikels führen wir Sie Schritt für Schritt durch den Abschluss des Projekts.
    • Der Ordner Complete enthält dasselbe Beispiel mit allen Codeschritten aus diesem Artikel. Um die vollständige Version zu verwenden, befolgen Sie einfach die Anweisungen in diesem Artikel, ersetzen Sie jedoch "Begin" durch "Complete", und überspringen Sie die Abschnitte Code the client side und Code the middle-tier server side.
  2. Öffnen Sie eine Eingabeaufforderung im Ordner Begin .

  3. Geben Sie npm install in die Konsole ein, um alle in der Datei „package.json“ aufgeführten Abhängigkeiten zu installieren.

  4. Führen Sie den Befehl npm run install-dev-certs aus. Wählen Sie Ja bei der entsprechenden Aufforderung, um das Zertifikat zu installieren.

Verwenden Sie die folgenden Werte für Platzhalter für die nachfolgenden App-Registrierungsschritte.

Platzhalter Wert
<add-in-name> Office-Add-in-NodeJS-SSO
<fully-qualified-domain-name> localhost:3000
Microsoft Graph-Berechtigungen profile, openid, Files.Read

Registrieren des Add-Ins bei Microsoft Identity Platform

Sie müssen eine App-Registrierung in Azure erstellen, die Ihren Webserver darstellt. Dadurch wird die Authentifizierungsunterstützung aktiviert, sodass geeignete Zugriffstoken für den Clientcode in JavaScript ausgestellt werden können. Diese Registrierung unterstützt sowohl das einmalige Anmelden im Client als auch die Fallbackauthentifizierung mithilfe der Microsoft Authentication Library (MSAL).

  1. Melden Sie sich beim Azure-Portal mit den Administratoranmeldeinformationen für Ihren Microsoft 365-Mandanten an. Beispiel: MyName@contoso.onmicrosoft.com.

  2. Wählen Sie App-Registrierungen aus. Wenn das Symbol nicht angezeigt wird, suchen Sie in der Suchleiste nach "App-Registrierung".

    Die Azure-Portal Startseite.

    Die Seite App-Registrierungen wird angezeigt.

  3. Wählen Sie Neue Registrierung aus.

    Neue Registrierung im bereich App-Registrierungen.

    Die Seite Anwendung registrieren wird angezeigt.

  4. Legen Sie auf der Seite Anwendung registrieren die Werte wie folgt fest.

    • Legen Sie Name auf <add-in-name> fest.
    • Legen Sie Unterstützte Kontotypen auf Konten in jedem Organisationsverzeichnis (beliebiges Azure AD-Verzeichnis – mehrinstanzenfähig) und persönliche Microsoft-Konten (z. B. Skype, Xbox) fest.
    • Legen Sie den Umleitungs-URI für die Verwendung der Plattform-Single-Page-Anwendung (SPA) und den URI auf fest https://<fully-qualified-domain-name>/dialog.html.

    Registrieren Sie einen Anwendungsbereich mit dem Namen und dem unterstützten Konto.

  5. Wählen Sie Registrieren aus. Es wird eine Meldung mit dem Hinweis angezeigt, dass die Anwendungsregistrierung erstellt wurde.

    Meldung, dass die Anwendungsregistrierung erstellt wurde.

  6. Kopieren und speichern Sie die Werte für die Anwendungs-ID (Client) und die Verzeichnis-ID (Mandant). Beide werden in späteren Verfahren verwendet.

    Bereich

Hinzufügen eines geheimen Clientschlüssels

Manchmal auch als Anwendungskennwort bezeichnet, ist ein geheimer Clientschlüssel ein Zeichenfolgenwert, den Ihre App anstelle eines Zertifikats verwenden kann, um sich selbst zu identifizieren.

  1. Wählen Sie im linken Bereich Zertifikate & Geheimnisse aus. Wählen Sie dann auf der Registerkarte Geheime Clientschlüsseldie Option Neuer geheimer Clientschlüssel aus.

    Der Bereich Zertifikate & Geheimnisse.

    Der Bereich Geheimen Clientschlüssel hinzufügen wird angezeigt.

  2. Fügen Sie eine Beschreibung für Ihren geheimen Clientschlüssel hinzu.

  3. Wählen Sie einen Ablauf für das Geheimnis aus, oder geben Sie eine benutzerdefinierte Lebensdauer an.

    • Die Lebensdauer des geheimen Clientschlüssels ist auf maximal zwei Jahre (24 Monate) beschränkt. Sie können keine benutzerdefinierte Lebensdauer angeben, die länger als 24 Monate ist.
    • Microsoft empfiehlt, einen Ablaufwert von weniger als 12 Monaten festzulegen.

    Hinzufügen eines Bereichs für geheimen Clientschlüssel mit beschreibung und ablaufen abgeschlossen.

  4. Wählen Sie Hinzufügen. Das neue Geheimnis wird erstellt, und der Wert wird vorübergehend angezeigt.

Wichtig

Notieren Sie sich den Wert des Geheimnisses zur Verwendung in Ihrem Clientanwendungscode. Dieser Geheimniswert wird nie wieder angezeigt , nachdem Sie diesen Bereich verlassen haben.

Verfügbarmachen einer Web-API

  1. Wählen Sie im linken Bereich Api verfügbar machen aus.

    Der Bereich API verfügbar machen wird angezeigt.

    Der Bereich

  2. Wählen Sie Festlegen aus, um einen Anwendungs-ID-URI zu generieren.

    Schaltfläche

    Der Abschnitt zum Festlegen des Anwendungs-ID-URI wird mit einem generierten Anwendungs-ID-URI im Format api://<app-id>angezeigt.

  3. Aktualisieren Sie den Anwendungs-ID-URI auf api://<fully-qualified-domain-name>/<app-id>.

    Bearbeiten Sie den Bereich App-ID-URI mit localhost-Port, der auf 44355 festgelegt ist.

    • Der Anwendungs-ID-URI wird mit der App-ID (GUID) im Format api://<app-id> vorausgefüllt.
    • Das URI-Format der Anwendungs-ID sollte wie folgt sein: api://<fully-qualified-domain-name>/<app-id>
    • Fügen Sie zwischen fully-qualified-domain-nameapi:// und <app-id> (eine GUID) ein. Beispiel: api://contoso.com/<app-id>.
    • Wenn Sie localhost verwenden, sollte das Format sein api://localhost:<port>/<app-id>. Beispiel: api://localhost:3000/c6c1f32b-5e55-4997-881a-753cc1d563b7.

    Weitere Informationen zum Anwendungs-ID-URI finden Sie unter Bezeichner-Attribut des Anwendungsmanifests.

    Hinweis

    Wenn eine Fehlermeldung angezeigt wird, die besagt, dass die Domäne bereits beansprucht wird, Sie jedoch der Eigentümer sind, folgen Sie dem Verfahren unter Schnellstart: Hinzufügen eines benutzerdefinierten Domänennamens zu Azure Active Directory, um sie zu registrieren. Wiederholen Sie dann den Vorgang. (Dieser Fehler kann auch auftreten, wenn Sie nicht mit den Anmeldeinformationen eines Administrators im Microsoft 365-Mandanten angemeldet sind. Siehe Schritt 2. Melden Sie sich ab, und melden Sie sich erneut mit Administratoranmeldeinformationen an, und wiederholen Sie den Vorgang aus Schritt 3.)

Hinzufügen eines Bereichs

  1. Wählen Sie auf der Seite API verfügbar machen die Option Bereich hinzufügen aus.

    Wählen Sie die Schaltfläche Bereich hinzufügen aus.

    Der Bereich Bereich hinzufügen wird geöffnet.

  2. Geben Sie im Bereich Bereich hinzufügen die Attribute des Bereichs an. Die folgende Tabelle enthält Beispielwerte für und das Outlook-Add-In, das die profileBerechtigungen , openid, Files.ReadWriteund Mail.Read erfordert. Ändern Sie den Text so, dass er den Berechtigungen entspricht, die Ihr Add-In benötigt.

    Feld Beschreibung Werte
    Bereichsname Der Name Ihres Bereichs. Eine gängige Benennungskonvention für Bereiche ist resource.operation.constraint. Für einmaliges Anmelden muss dies auf access_as_userfestgelegt werden.
    Wer kann zustimmen? Bestimmt, ob die Administratoreinwilligung erforderlich ist oder ob Benutzer ohne Administratorgenehmigung zustimmen können. Zum Erlernen des einmaligen Anmeldens und von Beispielen empfehlen wir, dies auf Administratoren und Benutzer festzulegen.

    Wählen Sie Nur Administratoren für Berechtigungen mit höheren Berechtigungen aus.
    Admin Anzeigename der Zustimmung Eine kurze Beschreibung des Zwecks des Bereichs, der nur für Administratoren sichtbar ist. Read/write permissions to user files. Read permissions to user mail and profiles.
    Admin Beschreibung der Einwilligung Eine ausführlichere Beschreibung der Berechtigung, die von dem Bereich gewährt wird, der nur Administratoren angezeigt wird. Allow Office to have read/write permissions to all user files and read permissions to all user mail. Office can call the app's web APIs as the current user.
    Anzeigename der Benutzer einwilligung Eine kurze Beschreibung des Zwecks des Bereichs. Wird benutzern nur angezeigt, wenn Sie Wer kann zustimmen für Administratoren und Benutzer festlegen. Read/write permissions to your files. Read permissions to your mail and profile.
    Beschreibung der Benutzer einwilligung Eine ausführlichere Beschreibung der berechtigung, die vom Bereich gewährt wird. Wird benutzern nur angezeigt, wenn Sie Wer kann zustimmen für Administratoren und Benutzer festlegen. Allow Office to have read/write permissions to your files, and read permissions to your mail and profile.
  3. Legen Sie den Status auf Aktiviert fest, und wählen Sie dann Bereich hinzufügen aus.

    Legen Sie den Status auf aktiviert fest, und wählen Sie die Schaltfläche Bereich hinzufügen aus.

    Der von Ihnen definierte neue Bereich wird im Bereich angezeigt.

    Der neue Bereich, der im Bereich Api verfügbar machen angezeigt wird.

    Hinweis

    Der Domänenteil des von Bereichsname, der direkt unter dem Textfeld angezeigt wird, sollte automatisch mit dem im vorherigen Schritt festgelegten Anwendungs-ID-URI übereinstimmen, mit /access_as_user am Ende angefügt, z. B. api://localhost:6789/c6c1f32b-5e55-4997-881a-753cc1d563b7/access_as_user.

  4. Hinzufügen einer Clientanwendung auswählen.

    Wählen Sie Clientanwendung hinzufügen aus.

    Der Bereich Clientanwendung hinzufügen wird angezeigt.

  5. Geben Sie in der Client-ID ein ea5a67f6-b6f3-4338-b240-c655ddc3cc8e. Mit diesem Wert werden alle Microsoft Office-Anwendungsendpunkte vorab autorisiert. Wenn Sie Office auch vorautorisieren möchten, wenn es innerhalb von Microsoft Teams verwendet wird, fügen Sie 1fec8e78-bce4-4aaf-ab1b-5451cc387264 (Microsoft Teams Desktop und Teams mobile) und 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 (Teams im Web) hinzu.

    Hinweis

    Die ea5a67f6-b6f3-4338-b240-c655ddc3cc8e ID autorisiert Office auf allen folgenden Plattformen vorab. Alternativ können Sie eine ordnungsgemäße Teilmenge der folgenden IDs eingeben, wenn Sie aus irgendeinem Grund die Autorisierung für Office auf einigen Plattformen verweigern möchten. Wenn Sie dies tun, lassen Sie die IDs der Plattformen weg, von denen Sie die Autorisierung verweigern möchten. Benutzer Ihres Add-Ins auf diesen Plattformen können Ihre Web-APIs nicht aufrufen, aber andere Funktionen in Ihrem Add-In funktionieren weiterhin.

    • d3590ed6-52b3-4102-aeff-aad2292ab01c (Microsoft Office)
    • 93d53678-613d-4013-afc1-62e9e444a0a5 (Office im Web)
    • bc59ab01-8403-45c6-8796-ac3ef710b3e3 (Outlook im Web)
  6. Aktivieren Sie unter Autorisierte Bereiche das api://<fully-qualified-domain-name>/<app-id>/access_as_user Kontrollkästchen.

  7. Wählen Sie Anwendung hinzufügen aus.

    Der Bereich Clientanwendung hinzufügen.

Hinzufügen von Microsoft Graph-Berechtigungen

  1. Wählen Sie im linken Bereich API-Berechtigungen aus.

    Der Bereich API-Berechtigungen.

    Der Bereich API-Berechtigungen wird geöffnet.

  2. Wählen Sie Berechtigung hinzufügen aus.

    Hinzufügen einer Berechtigung im Bereich

    Der Bereich API-Berechtigungen anfordern wird geöffnet.

  3. Wählen Sie Microsoft Graph aus.

    Der Bereich API-Berechtigungen anfordern mit der Microsoft Graph-Schaltfläche.

  4. Wählen Sie Delegierte Berechtigungen aus.

    Der Bereich API-Berechtigungen anfordern mit der Schaltfläche

  5. Suchen Sie im Suchfeld Berechtigungen auswählen nach den Berechtigungen, die Ihr Add-In benötigt. Für ein Outlook-Add-In können Sie beispielsweise , openid, Files.ReadWriteund Mail.Readverwendenprofile.

    Hinweis

    Die Berechtigung User.Read wird möglicherweise bereits standardmäßig aufgeführt. Es empfiehlt sich, nur berechtigungen anzufordern, die benötigt werden. Daher empfehlen wir Ihnen, das Kontrollkästchen für diese Berechtigung zu deaktivieren, wenn Ihr Add-In sie nicht benötigt.

  6. Aktivieren Sie das Kontrollkästchen für jede Berechtigung, wie sie angezeigt wird. Beachten Sie, dass die Berechtigungen in der Liste nicht sichtbar bleiben, wenn Sie jede auswählen. Nachdem Sie die Berechtigungen ausgewählt haben, die Ihr Add-In benötigt, wählen Sie Berechtigungen hinzufügen aus.

    Der Bereich API-Berechtigungen anfordern, in dem einige Berechtigungen ausgewählt sind.

  7. Wählen Sie Administratoreinwilligung für [Mandantenname] erteilen aus. Wählen Sie Ja für die angezeigte Bestätigung aus.

Konfigurieren der Zugriffstokenversion

Sie müssen die Zugriffstokenversion definieren, die für Ihre App akzeptabel ist. Diese Konfiguration erfolgt im Azure Active Directory-Anwendungsmanifest.

Definieren der Zugriffstokenversion

Die Version des Zugriffstokens kann sich ändern, wenn Sie einen anderen Kontotyp als Konten in einem Organisationsverzeichnis (Beliebiges Azure AD-Verzeichnis – mehrinstanzenfähig) und persönliche Microsoft-Konten (z. B. Skype, Xbox) ausgewählt haben. Führen Sie die folgenden Schritte aus, um sicherzustellen, dass die Zugriffstokenversion für die Verwendung von Office SSO korrekt ist.

  1. Wählen Sie im linken Bereich Manifest aus.

    Wählen Sie Azure-Manifest aus.

    Das Azure Active Directory-Anwendungsmanifest wird angezeigt.

  2. Geben Sie 2 als Wert für die Eigenschaft accessTokenAcceptedVersion ein.

    Wert für akzeptierte Zugriffstokenversion.

  3. Klicken Sie auf Speichern.

    Im Browser wird eine Meldung angezeigt, die besagt, dass das Manifest erfolgreich aktualisiert wurde.

    Aktualisierte Manifestnachricht.

Herzlichen Glückwunsch! Sie haben die App-Registrierung abgeschlossen, um einmaliges Anmelden für Ihr Office-Add-In zu aktivieren.

Konfigurieren des Add-Ins

  1. Öffnen Sie den Ordner \Begin im geklonten Projekt im Code-Editor.

  2. Öffnen Sie die .ENV Datei, und verwenden Sie die Werte, die Sie zuvor aus der Office-Add-in-NodeJS-SSO-App-Registrierung kopiert haben. Legen Sie die folgenden Werte fest:

    Name Wert
    CLIENT_ID Anwendungs-ID (Client) auf der Übersichtsseite der App-Registrierung.
    CLIENT_SECRET Auf der Seite Zertifikate & Geheimnisse gespeicherter geheimer Clientschlüssel.

    Die Werte dürfen nicht in Anführungszeichen stehen. Wenn Sie fertig sind, sollte Ihre Datei wie folgt aussehen:

    CLIENT_ID=8791c036-c035-45eb-8b0b-265f43cc4824
    CLIENT_SECRET=X7szTuPwKNts41:-/fa3p.p@l6zsyI/p
    NODE_ENV=development
    SERVER_SOURCE=<https://localhost:3000>
    
  3. Öffnen Sie die Add-In-Manifestdatei "manifest\manifest_local.xml", und scrollen Sie dann ans untere Ende der Datei. Direkt über dem </VersionOverrides> Endtag befindet sich das folgende Markup.

    <WebApplicationInfo>
      <Id>$app-id-guid$</Id>
      <Resource>api://localhost:3000/$app-id-guid$</Resource>
      <Scopes>
          <Scope>Files.Read</Scope>
          <Scope>profile</Scope>
          <Scope>openid</Scope>
      </Scopes>
    </WebApplicationInfo>
    
  4. Ersetzen Sie den Platzhalter "$app-id-guid$" an beiden Stellen im Markup durch die Anwendungs-ID , die Sie beim Erstellen der Office-Add-in-NodeJS-SSO-App-Registrierung kopiert haben. Die "$"-Symbole sind nicht Teil der ID, schließen Sie sie also nicht ein. Dies ist dieselbe ID, die Sie für die CLIENT_ID in verwendet haben. ENV-Datei.

    Hinweis

    Der <Wert Ressource> ist der Anwendungs-ID-URI , den Sie bei der Registrierung des Add-Ins festgelegt haben. Der Abschnitt Bereiche wird nur verwendet, um ein Zustimmungsdialogfeld> zu generieren, wenn das Add-In über AppSource verkauft wird.<

  5. die Datei \public\javascripts\fallback-msal\authConfig.js öffnen. Ersetzen Sie den Platzhalter "$app-id-guid$" durch die Anwendungs-ID, die Sie aus der zuvor erstellten Office-Add-in-NodeJS-SSO-App-Registrierung gespeichert haben.

  6. Speichern Sie die Änderungen an der Datei.

Codieren der Clientseite

Aufrufen unserer Webserver-REST-API

  1. Öffnen Sie die Datei public\javascripts\ssoAuthES6.js in Ihrem Code-Editor. Es verfügt bereits über Code, der sicherstellt, dass Promises auch im Webview-Steuerelement Trident (Internet Explorer 11) unterstützt werden, und ein Office.onReady Aufruf zum Zuweisen eines Handlers zur einzigen Schaltfläche des Add-Ins.

    Hinweis

    Wie der Name schon sagt, verwendet ssoAuthES6.js die JavaScript-Syntax "ES6", weil die Verwendung von async und await die wesentliche Einfachheit der SSO-API am besten zeigt. Wenn der localhost-Server gestartet wird, wird diese Datei in die ES5-Syntax transpiliert, sodass das Beispiel Trident unterstützt.

  2. Ersetzen Sie in der getFileNameList-Funktion TODO 1 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Die Funktion getFileNameList wird aufgerufen, wenn der Benutzer im Aufgabenbereich auf die Schaltfläche Get OneDrive File Names (OneDrive-Dateinamen abrufen ) klickt.
    • Sie ruft die callWebServerAPI Funktion auf, die angibt, welche REST-API aufgerufen werden soll. Dadurch wird JSON zurückgegeben, der eine Liste von Dateinamen aus dem OneDrive des Benutzers enthält.
    • Der JSON-Code wird an die writeFileNamesToOfficeDocument Funktion übergeben, um die Dateinamen im Dokument aufzulisten.
    try {
        const jsonResponse = await callWebServerAPI('GET', '/getuserfilenames');
        if (jsonResponse === null) {
            // Null is returned when a message was displayed to the user
            // regarding an authentication error that cannot be resolved.
            return;
        }
        await writeFileNamesToOfficeDocument(jsonResponse);
        showMessage('Your OneDrive filenames are added to the document.');
    } catch (error) {
        console.log(error.message);
        showMessage(error.message);
    }
    
  3. Ersetzen Sie in der callWebServerAPI-Funktion TODO 2 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Die Funktion ruft unsere eigene Funktion auf getAccessToken , die bei Bedarf das Office-SSO oder MSAL-Fallback zum Abrufen des Tokens kapselt. Wenn ein NULL-Token zurückgegeben wird, wurde eine Meldung für eine Authentifizierungsfehlerbedingung angezeigt, die nicht aufgelöst werden kann, sodass die Funktion ebenfalls NULL zurückgibt.
    • Die Funktion verwendet die fetch API zum Aufrufen des Webservers und gibt bei erfolgreicher Ausführung den JSON-Text zurück.
    const accessToken = await getAccessToken(authSSO);
    if (accessToken === null) {
        return null;
    }
    const response = await fetch(path, {
        method: method,
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + accessToken,
        },
    });
    
    // Check for success condition: HTTP status code 2xx.
    if (response.ok) {
        return response.json();
    }
    
  4. Ersetzen Sie in der callWebServerAPI-Funktion TODO 3 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Dieser Code behandelt das Szenario, in dem das SSO-Token abgelaufen ist. Wenn ja, müssen wir aufrufen Office.auth.getAccessToken , um ein aktualisiertes Token abzurufen. Die einfachste Möglichkeit besteht darin, einen rekursiven Aufruf zu erstellen, der zu einem neuen Aufruf von Office.auth.getAccessTokenführt. Der retryRequest Parameter stellt sicher, dass der rekursive Aufruf nur einmal versucht wird.
    • Die TokenExpiredError Zeichenfolge wird von unserem Webserver festgelegt, wenn er ein abgelaufenes Token erkennt.
     // Check for fail condition: Is SSO token expired? If so, retry the call which will get a refreshed token.
    const jsonBody = await response.json();
    if (
        authSSO === true &&
        jsonBody != null &&
        jsonBody.type === 'TokenExpiredError'
    ) {
        if (!retryRequest) {
            return callWebServerAPI(method, path, true); // Try the call again. The underlying call to Office JS getAccessToken will refresh the token.
        } else {
            // Indicates a second call to retry and refresh the token failed.
            authSSO = false;
            return callWebServerAPI(method, path, true); // Try the call again, but now using MSAL fallback auth.
        }
    }
    
  5. Ersetzen Sie in der callWebServerAPI-Funktion TODO 4 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Die Microsoft Graph Zeichenfolge wird von unserem Webserver festgelegt, wenn ein Microsoft Graph-Aufruf fehlschlägt.
    // Check for fail condition: Did we get a Microsoft Graph API error, which is returned as bad request (403)?
    if (response.status === 403 && jsonBody.type === 'Microsoft Graph') {
        throw new Error('Microsoft Graph error: ' + jsonBody.errorDetails);
    }
    
  6. Ersetzen Sie in der callWebServerAPI-Funktion TODO 5 durch den folgenden Code.

    // Handle other errors.
    throw new Error(
        'Unknown error from web server: ' + JSON.stringify(jsonBody)
    );
    
  7. Ersetzen Sie in der getAccessToken-Funktion TODO 6 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • authSSO verfolgt nach, ob wir SSO oder MSAL-Fallback verwenden. Wenn SSO verwendet wird, ruft die Funktion das Token auf Office.auth.getAccessToken und gibt es zurück.
    • Fehler werden von der handleSSOErrors Funktion behandelt, die ein Token zurückgibt, wenn sie zur FALLBACK-MSAL-Authentifizierung wechselt.
    • Die Fallbackauthentifizierung verwendet die MSAL-Bibliothek, um den Benutzer anzumelden. Das Add-In selbst ist eine SPA und verwendet eine SPA-App-Registrierung, um auf den Webserver zuzugreifen.
    if (authSSO) {
        try {
            // Get the access token from Office host using SSO.
            // Note that Office.auth.getAccessToken modifies the options parameter. Create a copy of the object
            // to avoid modifying the original object.
            const options = JSON.parse(JSON.stringify(ssoOptions));
            const token = await Office.auth.getAccessToken(options);
            return token;
        } catch (error) {
            console.log(error.message);
            return handleSSOErrors(error);
        }
    } else {
        // Get access token through MSAL fallback.
        try {
            const accessToken = await getAccessTokenMSAL();
            return accessToken;
        } catch (error) {
            console.log(error);
            throw new Error(
                'Cannot get access token. Both SSO and fallback auth failed. ' +
                    error
            );
        }
    }
    
  8. Ersetzen Sie in der handleSSOErrors-Funktion TODO 7 durch den folgenden Code. Weitere Informationen zu diesen Fehlern finden Sie unter Beheben von SSO-Problemen in Office Add-Ins.

    switch (error.code) {
        case 13001:
            // No one is signed into Office. If the add-in cannot be effectively used when no one
            // is logged into Office, then the first call of getAccessToken should pass the
            // `allowSignInPrompt: true` option. Since this sample does that, you should not see
            // this error.
            showMessage(
                'No one is signed into Office. But you can use many of the add-ins functions anyway. If you want to log in, press the Get OneDrive File Names button again.'
            );
            break;
        case 13002:
            // The user aborted the consent prompt. If the add-in cannot be effectively used when consent
            // has not been granted, then the first call of getAccessToken should pass the `allowConsentPrompt: true` option.
            showMessage(
                'You can use many of the add-ins functions even though you have not granted consent. If you want to grant consent, press the Get OneDrive File Names button again.'
            );
            break;
        case 13006:
            // Only seen in Office on the web.
            showMessage(
                'Office on the web is experiencing a problem. Please sign out of Office, close the browser, and then start again.'
            );
            break;
        case 13008:
            // Only seen in Office on the web.
            showMessage(
                'Office is still working on the last operation. When it completes, try this operation again.'
            );
            break;
        case 13010:
            // Only seen in Office on the web.
            showMessage(
                "Follow the instructions to change your browser's zone configuration."
            );
            break;
    
  9. Ersetzen Sie TODO 8 durch den folgenden Code. Bei Fehlern, die nicht behandelt werden können, wechselt der Code zur Fallbackauthentifizierung mithilfe von MSAL.

    default: //recursive call.
            // For all other errors, including 13000, 13003, 13005, 13007, 13012, and 50001, fall back
            // to MSAL sign-in.
            showMessage('SSO failed. Trying fallback auth.');
            authSSO = false;
            return getAccessToken(false);
    }
    return null; // Return null for errors that show a message to the user.
    

Programmieren der Webserver-REST-API

Der Webserver stellt REST-APIs bereit, die vom Client aufgerufen werden können. Beispielsweise ruft die REST-API /getuserfilenames eine Liste von Dateinamen aus dem OneDrive-Ordner des Benutzers ab. Jeder REST-API-Aufruf erfordert ein Zugriffstoken vom Client, um sicherzustellen, dass der richtige Client auf seine Daten zugreift. Das Zugriffstoken wird über den On-Behalf-Of-Flow (OBO) gegen ein Microsoft Graph-Token ausgetauscht. Das neue Microsoft Graph-Token wird von der MSAL-Bibliothek für nachfolgende API-Aufrufe zwischengespeichert. Es wird nie außerhalb des Webservers gesendet. Weitere Informationen finden Sie unter Zugriffstokenanforderung der mittleren Ebene.

Erstellen der Route und Implementieren des On-Behalf-Of-Flusses

  1. Öffnen Sie die Datei, routes\getFilesRoute.js und ersetzen Sie durch TODO 9 den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Sie ruft auf authHelper.validateJwt. Dadurch wird sichergestellt, dass das Zugriffstoken gültig ist und nicht manipuliert wurde.
    • Weitere Informationen finden Sie unter Überprüfen von Token.
    router.get(
     "/getuserfilenames",
     authHelper.validateJwt,
     async function (req, res) {
       // TODO 10: Exchange the access token for a Microsoft Graph token
       //          by using the OBO flow.
     }
    );
    
  2. Ersetzen Sie TODO 10 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Es fordert nur die mindest erforderlichen Bereiche an, z files.read. B. .
    • Es verwendet die MSAL authHelper , um den OBO-Fluss im Aufruf von auszuführen acquireTokenOnBehalfOf.
    try {
      const authHeader = req.headers.authorization;
      let oboRequest = {
        oboAssertion: authHeader.split(' ')[1],
        scopes: ["files.read"],
      };
    
      // The Scope claim tells you what permissions the client application has in the service.
      // In this case we look for a scope value of access_as_user, or full access to the service as the user.
      const tokenScopes = jwt.decode(oboRequest.oboAssertion).scp.split(' ');
      const accessAsUserScope = tokenScopes.find(
        (scope) => scope === 'access_as_user'
      );
      if (!accessAsUserScope) {
        res.status(401).send({ type: "Missing access_as_user" });
        return;
      }
      const cca = authHelper.getConfidentialClientApplication();
      const response = await cca.acquireTokenOnBehalfOf(oboRequest);
      // TODO 11: Call Microsoft Graph to get list of filenames.
    } catch (err) {
      // TODO 12: Handle any errors.
    }
    
  3. Ersetzen Sie TODO 11 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Es erstellt die URL für den Microsoft Graph-API-Aufruf und führt dann den Aufruf über die -Funktion ausgetGraphData.
    • Es gibt Fehler zurück, indem eine HTTP 500-Antwort zusammen mit Details gesendet wird.
    • Bei Erfolg wird der JSON-Code mit der Dateinamenliste an den Client zurückgegeben.
    // Minimize the data that must come from MS Graph by specifying only the property we need ("name")
    // and only the top 10 folder or file names.
    const rootUrl = '/me/drive/root/children';
    
    // Note that the last parameter, for queryParamsSegment, is hardcoded. If you reuse this code in
    // a production add-in and any part of queryParamsSegment comes from user input, be sure that it is
    // sanitized so that it cannot be used in a Response header injection attack.
    const params = '?$select=name&$top=10';
    
    const graphData = await getGraphData(
      response.accessToken,
      rootUrl,
      params
    );
    
    // If Microsoft Graph returns an error, such as invalid or expired token,
    // there will be a code property in the returned object set to a HTTP status (e.g. 401).
    // Return it to the client. On client side it will get handled in the fail callback of `makeWebServerApiCall`.
    if (graphData.code) {
      res
        .status(403)
        .send({
          type: "Microsoft Graph",
          errorDetails:
            "An error occurred while calling the Microsoft Graph API.\n" +
            graphData,
        });
    } else {
      // MS Graph data includes OData metadata and eTags that we don't need.
      // Send only what is actually needed to the client: the item names.
      const itemNames = [];
      const oneDriveItems = graphData["value"];
      for (let item of oneDriveItems) {
        itemNames.push(item["name"]);
      }
    
      res.status(200).send(itemNames);
    }
    // TODO 12: Check for expired token.
    
  4. Ersetzen Sie TODO 12 durch den folgenden Code. Dieser Code überprüft insbesondere, ob das Token abgelaufen ist, da der Client ein neues Token anfordern und erneut aufrufen kann.

    } catch (err) {
       // On rare occasions the SSO access token is unexpired when Office validates it,
       // but expires by the time it is used in the OBO flow. Microsoft identity platform will respond
       // with "The provided value for the 'assertion' is not valid. The assertion has expired."
       // Construct an error message to return to the client so it can refresh the SSO token.
       if (err.errorMessage.indexOf('AADSTS500133') !== -1) {
         res.status(401).send({ type: "TokenExpiredError", errorDetails: err });
       } else {
         res.status(403).send({ type: "Unknown", errorDetails: err });
       }
    }
    

Das Beispiel muss sowohl die Fallbackauthentifizierung über MSAL als auch die SSO-Authentifizierung über Office behandeln. Im Beispiel wird zuerst SSO ausprobiert, und der authSSO boolesche Wert am Anfang der Datei verfolgt, ob das Beispiel SSO verwendet oder zur Fallbackauthentifizierung gewechselt ist.

Ausführen des Projekts

  1. Stellen Sie sicher, dass einige Dateien in OneDrive gespeichert sind, damit Sie die Ergebnisse überprüfen können.

  2. Öffnen Sie eine Eingabeaufforderung im \Begin-Ordner.

  3. Führen Sie den Befehl aus npm install , um alle Paketabhängigkeiten zu installieren.

  4. Führen Sie den Befehl aus npm start , um den Server der mittleren Ebene zu starten.

  5. Sie müssen das Add-In in einer Office-Anwendung (Excel, Word oder PowerPoint) querladen, um es zu testen. Die entsprechenden Anweisungen sind je nach Plattform unterschiedlich. Links zu den Anweisungen finden Sie unter Querladen eines Office-Add-Ins zu Testzwecken.

  6. Wählen Sie in der Office-Anwendung im Menüband Start die Schaltfläche Add-In anzeigen in der Gruppe SSO Node.js aus, um das Add-In des Aufgabenbereichs zu öffnen.

  7. Klicken Sie auf die Schaltfläche OneDrive-Dateinamen abrufen. Wenn Sie bei Office mit einem Microsoft 365 Education- oder Geschäftskonto oder einem Microsoft-Konto angemeldet sind und einmaliges Anmelden wie erwartet funktioniert, werden die ersten 10 Datei- und Ordnernamen in Ihrem OneDrive for Business in das Dokument eingefügt. (Beim ersten Mal kann es bis zu 15 Sekunden dauern.) Wenn Sie nicht angemeldet sind oder sich in einem Szenario befindet, das SSO nicht unterstützt oder SSO aus irgendeinem Grund nicht funktioniert, werden Sie aufgefordert, sich anzumelden. Nach der Anmeldung werden die Datei- und Ordnernamen angezeigt.

Hinweis

Wenn Sie zuvor mit einer anderen ID bei Office angemeldet waren und einige Office-Programme, die zu diesem Zeitpunkt geöffnet waren, noch geöffnet sind, ändert Office möglicherweise nicht zuverlässig Ihre ID, auch wenn es so scheint. Wenn dies der Fall ist, schlägt der Aufruf von Microsoft Graph evtl. fehl oder es werden u. U. Daten aus der vorherigen ID zurückgegeben. Um dies zu verhindern, schließen Sie alle anderen Office-Anwendungen, bevor Sie auf OneDrive-Dateinamen abrufen klicken.

Sicherheitshinweise

  • Die /getuserfilenames Route in getFilesroute.js verwendet eine Literalzeichenfolge, um den Aufruf für Microsoft Graph zu verfassen. Wenn Sie den Aufruf so ändern, dass ein Teil der Zeichenfolge von einer Benutzereingabe stammt, bereinigen Sie die Eingabe, damit sie nicht bei einem Angriff mit Einschleusung von Response-Headern verwendet werden kann.

  • In app.js der folgenden Inhaltssicherheitsrichtlinie ist für Skripts vorhanden. Abhängig von den Sicherheitsanforderungen Ihres Add-Ins können Sie zusätzliche Einschränkungen angeben.

    "Content-Security-Policy": "script-src https://appsforoffice.microsoft.com https://ajax.aspnetcdn.com https://alcdn.msauth.net " + process.env.SERVER_SOURCE,

Befolgen Sie immer die bewährten Sicherheitsmethoden in der Microsoft Identity Platform-Dokumentation.