Erstellen eines ASP.NET-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. Dieser Artikel führt Sie durch den Prozess der Aktivierung des einmaligen Anmeldens (Single Sign-On, SSO) in einem Add-In.

Das Beispiel zeigt, wie Sie die folgenden Teile erstellen:

  • Clientseitiger Code, der einen Aufgabenbereich bereitstellt, der in Microsoft Excel, Word oder PowerPoint geladen wird. Der clientseitige Code ruft die Office JS-API getAccessToken() auf, um das SSO-Zugriffstoken zum Aufrufen serverseitiger REST-APIs abzurufen.
  • Serverseitiger Code, der ASP.NET Core verwendet, um eine einzelne REST-API /api/filesbereitzustellen. Der serverseitige Code verwendet die Microsoft-Authentifizierungsbibliothek für .NET (MSAL.NET) für die gesamte Tokenverarbeitung, Authentifizierung und Autorisierung.

Im Beispiel werden SSO und der OBO-Fluss (On-Behalf-Of) verwendet, um korrekte Zugriffstoken zu erhalten und Microsoft Graph-APIs aufzurufen. Wenn Sie mit der Funktionsweise dieses Flows nicht vertraut sind, finden Sie weitere Informationen unter Funktionsweise von SSO zur Laufzeit .

Voraussetzungen

  • Visual Studio 2019 oder höher.

  • Die Office/SharePoint-Entwicklungsworkload beim Konfigurieren von Visual Studio.

  • 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

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

Hinweis

Es gibt zwei Versionen des Beispiels.

  • 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 fertige 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 server side.

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

Platzhalter Wert
<add-in-name> Office-Add-in-ASPNET-SSO
<fully-qualified-domain-name> localhost:44355
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 der Lösung

  1. Öffnen Sie im Stammverzeichnis des Ordners Begin die Projektmappendatei (.sln) in Visual Studio. Klicken Sie mit der rechten Maustaste oben im Projektmappen-Explorer auf den obersten Knoten (der Projektmappenknoten, nicht einer der Projektknoten), und wählen Sie Startprojekte festlegen aus.

  2. Wählen Sie unter Allgemeine EigenschaftenStartprojekt und dann Mehrere Startprojekte aus. Stellen Sie sicher, dass die Aktion für beide Projekte auf Start festgelegt ist und dass das Projekt Office-Add-in-ASPNETCoreWebAPI zuerst aufgeführt wird. Schließen Sie das Dialogfeld.

  3. Wählen Sie in Projektmappen-Explorer das Projekt Office-Add-in-ASPNET-SSO-manifest aus, öffnen Sie die Add-In-Manifestdatei "Office-Add-in-ASPNET-SSO.xml", und scrollen Sie dann zum Ende der Datei. Direkt über dem Endtag </VersionOverrides> befindet sich das folgende Markup.

    <WebApplicationInfo>
         <Id>Enter_client_ID_here</Id>
     	<Resource>api://localhost:44355/Enter_client_ID_here</Resource>
     	<Scopes>
            <Scope>Files.Read</Scope>
     		<Scope>profile</Scope>
            <Scope>openid</Scope>
     	</Scopes>
     </WebApplicationInfo>
    
  4. Ersetzen Sie den Platzhalter "Enter_client_ID_here" an beiden Stellen im Markup durch die Anwendungs-ID , die Sie beim Erstellen der Office-Add-in-ASPNET-SSO-App-Registrierung kopiert haben. Dies ist dieselbe ID, die Sie für die Anwendungs-ID in der appsettings.json-Datei verwendet haben.

    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. Speichern und schließen Sie die Manifestdatei.

  6. Wählen Sie Projektmappen-Explorer das Projekt Office-Add-in-ASPNET-SSO-web aus, und öffnen Sie die datei appsettings.json.

  7. Ersetzen Sie den Platzhalter Enter_client_id_here durch den Wert der Anwendungs-ID (Client-ID), den Sie zuvor gespeichert haben.

  8. Ersetzen Sie den Platzhalter Enter_client_secret_here durch den Wert des geheimen Clientschlüssels, den Sie zuvor gespeichert haben.

    Hinweis

    Sie müssen auch die TenantId ändern, um einen einzelnen Mandanten zu unterstützen, wenn Sie Ihre App-Registrierung für einen einzelnen Mandanten konfiguriert haben. Ersetzen Sie den Wert Common durch die Anwendungs-ID (Client) für die Einzelmandantenunterstützung.

  9. Speichern und schließen Sie die appsettings.json Datei.

Codieren der Clientseite

Abrufen des Zugriffstokens und Aufrufen der Anwendungsserver-REST-API

  1. Öffnen Sie im Projekt Office-Add-in-ASPNETCore-WebAPI die dateiwwwroot\js\HomeES6.js . 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 die HomeES6.js JavaScript ES6-Syntax, da die Verwendung von async und await am besten die wesentliche Einfachheit der SSO-API 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 getUserFileNames-Funktion TODO 1 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Sie ruft auf Office.auth.getAccessToken , um das Zugriffstoken von Office mithilfe von SSO abzurufen. Dieses Token enthält die Identität des Benutzers sowie die Zugriffsberechtigung für den Anwendungsserver.
    • Das Zugriffstoken wird an callRESTApi übergeben, wodurch der eigentliche Aufruf des Anwendungsservers erfolgt. Der Anwendungsserver verwendet dann den OBO-Fluss, um Microsoft Graph aufzurufen.
    • Alle Fehler beim Aufrufen getAccessToken werden von handleClientSideErrorsbehandelt.
       let fileNameList = null;
    try {
        let accessToken = await Office.auth.getAccessToken(options);
        fileNameList = await callRESTApi("/api/files", accessToken);
    }
    catch (exception) {
        if (exception.code) {
            handleClientSideErrors(exception);
        }
        else {
            showMessage("EXCEPTION: " + exception);
        }
    }
    
    
  3. Ersetzen Sie in der getUserFileNames-Funktion TODO 2 durch den folgenden Code. Dadurch wird die Liste der Dateinamen in das Dokument geschrieben.

     try {
         await writeFileNamesToOfficeDocument(fileNameList);
         showMessage("Your data has been added to the document.");
     } catch (error) {
         // The error from writeFileNamesToOfficeDocument will begin 
         // "Unable to add filenames to document."
         showMessage(error);
     }
    
  4. Ersetzen Sie in der callRESTApi-Funktion TODO 3 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Er erstellt einen Autorisierungsheader, der das Zugriffstoken enthält. Dadurch wird dem Anwendungsserver bestätigt, dass dieser Clientcode über Zugriffsberechtigungen für die REST-APIs verfügt.
    • Er fordert JSON-Rückgabetypen an, sodass alle Rückgabewerte in JSON behandelt werden.
    • Alle Fehler werden zur Verarbeitung an handleServerSideErrors übergeben.
     try {
         let result = await $.ajax({
             url: relativeUrl,
             headers: { "Authorization": "Bearer " + accessToken },
             type: "GET",
             dataType: "json",
             contentType: "application/json; charset=utf-8"
         });
         return result;
     } catch (error) {
         handleServerSideErrors(error);
     }
    

Behandeln von SSO-Fehlern und Anwendungs-REST-API-Fehlern

  1. Ersetzen Sie in der handleSSOErrors-Funktion TODO 4 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.
             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;
         default:
             // For all other errors, including 13000, 13003, 13005, 13007, 13012, and 50001, fall back
             // to non-SSO sign-in by using MSAL authentication.
             showMessage("SSO failed. In these cases you should implement a falback to MSAL authentication.");
             break;
     }
    
  2. Ersetzen Sie in der handleServerSideErrors-Funktion TODO 5 durch den folgenden Code.

    // Check headers to see if admin has not consented.
    const header = errorResponse.getResponseHeader('WWW-Authenticate');
    if (header !== null && header.includes('proposedAction=\"consent\"')) {
        showMessage("MSAL ERROR: " + "Admin consent required. Be sure admin consent is granted on all scopes in the Azure app registration.");
        return;
    }
    
    
  3. Ersetzen Sie in der handleServerSideErrors-Funktion TODO 6 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • In einigen Fällen ist eine zusätzliche Zustimmung erforderlich, z. B. 2FA. Microsoft Identity gibt die zusätzlichen Ansprüche zurück, die zum Abschließen der Zustimmung erforderlich sind. Dieser Code fügt die authChallenge -Eigenschaft mit den zusätzlichen Ansprüchen hinzu und ruft erneut auf getUserfileNames . Wenn getAccessToken mit den zusätzlichen Ansprüchen erneut aufgerufen wird, erhält der Benutzer eine Aufforderung für alle erforderlichen Authentifizierungsformen.
    // Check if Microsoft Graph requires an additional form of authentication. Have the Office host 
    // get a new token using the Claims string, which tells Microsoft identity to prompt the user for all 
    // required forms of authentication.
    const errorDetails = JSON.parse(errorResponse.responseJSON.value.details);
    if (errorDetails) {
        if (errorDetails.error.message.includes("AADSTS50076")) {
            const claims = errorDetails.message.Claims;
            const claimsAsString = JSON.stringify(claims);
            getUserFileNames({ authChallenge: claimsAsString });
            return;
        }
    }
    
  4. Ersetzen Sie in der handleServerSideErrors-Funktion TODO 7 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • In dem seltenen Fall, dass das ursprüngliche SSO-Token abgelaufen ist, wird diese Fehlerbedingung erkannt und erneut aufgerufen getUserFilenames . Dies führt zu einem weiteren Aufruf von, der getAccessToken ein aktualisiertes Zugriffstoken zurückgibt. Die retryGetAccessToken Variable zählt die Wiederholungen und ist derzeit so konfiguriert, dass nur einmal versucht wird.
    • Wenn ein Fehler nicht behandelt werden kann, wird der Fehler standardmäßig im Aufgabenbereich angezeigt.
    // Results from other errors (other than AADSTS50076) will have an ExceptionMessage property.
    const exceptionMessage = JSON.parse(errorResponse.responseText).ExceptionMessage;
    if (exceptionMessage) {
        // On rare occasions the access token is unexpired when Office validates it,
        // but expires by the time it is sent to Microsoft identity in the OBO flow. Microsoft identity will respond
        // with "The provided value for the 'assertion' is not valid. The assertion has expired."
        // Retry the call of getAccessToken (no more than once). This time Office will return a 
        // new unexpired access token.
        if ((exceptionMessage.includes("AADSTS500133"))
            && (retryGetAccessToken <= 0)) {
            retryGetAccessToken++;
            getUserFileNames();
            return;
        }
        else {
            showMessage("MSAL error from application server: " + JSON.stringify(exceptionMessage));
            return;
        }
    }
    // Default error handling if previous checks didn't apply.
    showMessage(errorResponse.responseJSON.value);
    
  5. Speichern Sie die Datei.

Programmieren der Serverseite

Der serverseitige Code ist ein ASP.NET Core Server, der REST-APIs bereitstellt, die der Client aufrufen kann. Beispielsweise ruft die REST-API /api/files 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.NET-Bibliothek für nachfolgende API-Aufrufe zwischengespeichert. Es wird nie außerhalb des serverseitigen Codes gesendet. Die Microsoft-Identitätsdokumentation bezeichnet diesen Server als Server der mittleren Ebene, da er sich in der Mitte des Flusses vom clientseitigen Code zu Microsoft-Diensten befindet. Weitere Informationen finden Sie unter Zugriffstokenanforderung der mittleren Ebene.

Konfigurieren des Microsoft Graph- und OBO-Flusses

  1. Öffnen Sie die Program.cs Datei, und ersetzen Sie durch TODO 8 den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Sie fügt erforderliche Dienste für die Tokenüberprüfung hinzu, die für die REST-APIs erforderlich ist.
    • Es fügt Microsoft Graph- und OBO-Flowunterstützung im Aufruf von hinzu EnableTokenAcquisitionToCallDownstreamApi().AddMicrosoftGraph(...). Der OBO-Flow wird automatisch für Sie verarbeitet, und das Microsoft Graph SDK wird für Ihre REST-API-Controller bereitgestellt.
    • Die DownstreamApi-Konfiguration wird in der appsettings.json-Datei angegeben.
    // Add services to the container.
    builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
                    .EnableTokenAcquisitionToCallDownstreamApi()
                        .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi"))
                        .AddInMemoryTokenCaches();
    
    

Erstellen der REST-API "/api/filenames"

  1. Öffnen Sie im Ordner Controller die datei FilesController.cs . ersetzen Sie TODO 9 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Es gibt das [Authorize] -Attribut an, um sicherzustellen, dass das Zugriffstoken für jeden Aufruf von REST-APIs in der FilesController Klasse überprüft wird. Weitere Informationen finden Sie unter Überprüfen von Token.
    • Es gibt das [RequiredScope("access_as_user")] -Attribut an, um sicherzustellen, dass der Client über den richtigen access_as_user Bereich im Zugriffstoken verfügt.
    • Der Konstruktor initialisiert das _graphServiceClient -Objekt, um das Aufrufen von Microsoft Graph-REST-APIs zu vereinfachen.
    [Authorize]
    [Route("api/[controller]")]
    [RequiredScope("access_as_user")]
    public class FilesController : Controller
    {        
        public FilesController(ITokenAcquisition tokenAcquisition, GraphServiceClient graphServiceClient, IOptions<MicrosoftGraphOptions> graphOptions)
        {
            _tokenAcquisition = tokenAcquisition;
            _graphServiceClient = graphServiceClient;
            _graphOptions = graphOptions;
    
        }
    
        private readonly ITokenAcquisition _tokenAcquisition;
        private readonly GraphServiceClient _graphServiceClient;
        private readonly IOptions<MicrosoftGraphOptions> _graphOptions;
    
        // TODO 10: Add the REST API to get filenames.
    
    }
    
  2. Ersetzen Sie TODO 10 durch den folgenden Code. Bei diesem Code ist Folgendes zu beachten:

    • Es wird die /api/files REST-API erstellt.
    • Es behandelt Ausnahmen von MSAL über die MsalException -Klasse.
    • Es verarbeitet Ausnahmen von Microsoft Graph-API Aufrufen über die ServiceException -Klasse.
     // GET api/files
        [HttpGet]
        [Produces("application/json")]
        public async Task<IActionResult> Get()
        {
            List<DriveItem> result = new List<DriveItem>();
            try
            {
                var files = await _graphServiceClient.Me.Drive.Root.Children.Request()
                    .Top(10)
                    .Select(m => new { m.Name })
                    .GetAsync();
    
                result = files.ToList();
            }
            catch (MsalException ex)
            {
                var errorResponse = new
                {
                    message = "An authentication error occurred while acquiring a token for downstream API",
                    details = ex.Message
                };
    
                return StatusCode((int)HttpStatusCode.Unauthorized, Json(errorResponse));
            }
            catch (ServiceException ex)
            {
                if (ex.InnerException is MicrosoftIdentityWebChallengeUserException challengeException)
                {
                    _tokenAcquisition.ReplyForbiddenWithWwwAuthenticateHeader(_graphOptions.Value.Scopes.Split(' '),
                        challengeException.MsalUiRequiredException);
                }
                else
                {
                    var errorResponse = new
                    {
                        message = "An error occurred calling Microsoft Graph",
                        details = ex.RawResponseBody
                    };
                    return StatusCode((int)HttpStatusCode.BadRequest, Json(errorResponse));
                }
            }
            catch (Exception ex)
            {
                var errorResponse = new
                {
                    message = "An error occurred while calling the downstream API",
                    details = ex.Message
                };
                return StatusCode((int)HttpStatusCode.BadRequest, Json(errorResponse));
    
            }
            return Json(result);
        }
    

Führen Sie die Projektmappe aus.

  1. Wählen Sie in Visual Studio im Menü Erstellen die Option Projektmappe bereinigen aus. Wenn der Vorgang abgeschlossen ist, öffnen Sie das Menü Erstellen, und wählen Sie Projektmappe erstellen aus.

  2. Wählen Sie Projektmappen-Explorer den Projektknoten Office-Add-in-ASPNET-SSO-manifest aus.

  3. Öffnen Sie im Bereich Eigenschaften das Dropdown-Menü Dokument starten und wählen Sie eine der drei Optionen (Excel, Word oder PowerPoint).

    Wählen Sie die gewünschte Office-Clientanwendung aus: Excel, PowerPoint oder Word.

  4. Drücken Sie F5. Oder wählen Sie Debuggen > Debuggen starten aus.

  5. Wählen Sie in der Office-Anwendung die Gruppe Add-In anzeigen in der Gruppe SSO ASP.NET aus, um das Aufgabenbereich-Add-In zu öffnen.

  6. Wählen Sie OneDrive-Dateinamen abrufen aus. Wenn Sie mit einem Microsoft 365 Education- oder Geschäftskonto oder einem Microsoft-Konto bei Office angemeldet sind und einmaliges Anmelden wie erwartet funktioniert, werden die ersten 10 Datei- und Ordnernamen in Ihrem OneDrive for Business im Aufgabenbereich angezeigt. Wenn Sie nicht angemeldet sind oder sich in einem Szenario befinden, 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.

Bereitstellen des Add-Ins

Wenn Sie bereit für die Bereitstellung auf einem Staging- oder Produktionsserver sind, müssen Sie die folgenden Bereiche in der Projektmappe aktualisieren.

  • Ändern Sie in der appsettings.json-Datei die Domäne in Ihren Staging- oder Produktionsdomänennamen.
  • Aktualisieren Sie alle Verweise auf localhost:7080 im gesamten Projekt, um Ihre Staging- oder Produktions-URL zu verwenden.
  • Aktualisieren Sie alle Verweise auf localhost:7080 in Ihrer Azure-App Registrierung, oder erstellen Sie eine neue Registrierung für die Verwendung in Staging oder Produktion.

Weitere Informationen finden Sie unter Hosten und Bereitstellen von ASP.NET Core.

Siehe auch