Hinzufügen von Code zum Aktivieren des einmaligen Anmeldens in Ihrer Bot-App

Bevor Sie Code zum Aktivieren des einmaligen Anmeldens (Single Sign-On, SSO) hinzufügen, stellen Sie sicher, dass Sie Ihre App und Botressource im Microsoft Entra Admin Center konfiguriert haben.

Sie müssen den Code Ihrer App so konfigurieren, dass ein Zugriffstoken von Microsoft Entra ID abgerufen wird. Das Zugriffstoken wird im Auftrag der Bot-App ausgestellt.

Hinweis

Wenn Sie Ihre Teams-App mit dem Microsoft Teams Toolkit erstellt haben, können Sie SSO für Ihre App aktivieren, indem Sie die Anweisungen im Modul Tools und SDKs verwenden. Weitere Informationen finden Sie unter Hinzufügen des einmaligen Anmeldens zur Teams-App. Teams Toolkit unterstützt SSO für JavaScript- und TypeScript-Apps in Visual Studio Code und in Teams Toolkit 17.4 Preview 3 für C#-Apps.

In diesem Abschnitt werden folgende Themen behandelt:

  1. Aktualisieren von Entwicklungsumgebungsvariablen
  2. Hinzufügen von Code zum Verarbeiten eines Zugriffstokens
  3. Hinzufügen von Code zum Empfangen des Tokens
  4. Behandeln der Abmeldung von App-Benutzern

Aktualisieren von Entwicklungsumgebungsvariablen

Sie haben den geheimen Clientschlüssel und die OAuth-Verbindungseinstellung für die App in Microsoft Entra-ID konfiguriert. Sie müssen den Code mit diesen Werten konfigurieren.

So aktualisieren Sie die Entwicklungsumgebungsvariablen:

  1. Öffnen Sie das Bot-App-Projekt.

  2. Öffnen Sie die Umgebungsdatei für Ihr Projekt.

  3. Aktualisieren Sie die folgenden Variablen:

    • Aktualisieren MicrosoftAppIdSie für die Bot-ID von Microsoft Entra ID.
    • Aktualisieren MicrosoftAppPasswordSie für den geheimen Clientschlüssel.
    • ConnectionNameAktualisieren Sie für den Namen der OAuth-Verbindung, die Sie in Microsoft Entra ID konfiguriert haben.
    • Aktualisieren MicrosoftAppTenantIdSie für die Mandanten-ID.
  4. Speichern Sie die Datei.

Sie haben nun die erforderlichen Umgebungsvariablen für Ihre Bot-App und SSO konfiguriert. Fügen Sie als Nächstes den Code für die Verarbeitung von Bottoken hinzu.

Hinzufügen von Code zum Verarbeiten eines Zugriffstokens

Die Anforderung zum Abrufen des Tokens ist eine POST-Nachrichtenanforderung, die das vorhandene Nachrichtenschema verwendet. Es ist in den Anhängen einer OAuthCard enthalten. Das Schema für die OAuthCard-Klasse ist in Microsoft Bot Schema 4.0 definiert. Teams aktualisiert das Token, wenn die TokenExchangeResource Eigenschaft auf dem Karte aufgefüllt wird. Für den Teams-Kanal wird nur die Eigenschaft Id berücksichtigt, die eine Tokenanforderung eindeutig identifiziert.

Hinweis

Das Microsoft Bot Framework OAuthPrompt oder MultiProviderAuthDialog wird für die SSO-Authentifizierung unterstützt.

So aktualisieren Sie den Code Ihrer App:

  1. Fügen Sie Codeausschnitt für TeamsSSOTokenExchangeMiddlewarehinzu.

    Fügen Sie den folgenden Codeausschnitt zu AdapterWithErrorHandler.cs (oder der entsprechenden Klasse im Code Ihrer App) hinzu:

    base.Use(new TeamsSSOTokenExchangeMiddleware(storage, configuration["ConnectionName"]));
    

    Hinweis

    Sie erhalten möglicherweise mehrere Antworten für eine bestimmte Anfrage, wenn der Benutzer mehrere aktive Endpunkte hat. Sie müssen alle doppelten oder redundanten Antworten mit dem Token entfernen. Weitere Informationen zu signin/tokenExchange finden Sie unter TeamsSSOTokenExchangeMiddleware-Klasse.

  2. Verwenden Sie den folgenden Codeausschnitt, um ein Token anzufordern.

    Nachdem Sie hinzugefügt haben AdapterWithErrorHandler.cs, muss der folgende Code angezeigt werden:

        public class AdapterWithErrorHandler : CloudAdapter
        {
            public AdapterWithErrorHandler(
                IConfiguration configuration,
                IHttpClientFactory httpClientFactory,
                ILogger<IBotFrameworkHttpAdapter> logger,
                IStorage storage,
                ConversationState conversationState)
                : base(configuration, httpClientFactory, logger)
            {
                base.Use(new TeamsSSOTokenExchangeMiddleware(storage, configuration["ConnectionName"]));
    
                OnTurnError = async (turnContext, exception) =>
                {
                    // Log any leaked exception from the application.
                    // NOTE: In production environment, you must consider logging this to
                    // Azure Application Insights. Visit https://learn.microsoft.com/azure/bot-service/bot-builder-telemetry?view=azure-bot-service-4.0&tabs=csharp to see how
                    // to add telemetry capture to your bot.
                    logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");
    
                    // Send a message to the user.
                    await turnContext.SendActivityAsync("The bot encountered an error or bug.");
                    await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");
    
                    if (conversationState != null)
                    {
                        try
                        {
                            // Delete the conversationState for the current conversation to prevent the
                            // bot from getting stuck in a error-loop caused by being in a bad state.
                            // conversationState must be thought of as similar to "cookie-state" in a Web pages.
                            await conversationState.DeleteAsync(turnContext);
                        }
                        catch (Exception e)
                        {
                            logger.LogError(e, $"Exception caught on attempting to Delete ConversationState : {e.Message}");
                        }
                    }
    
                    // Send a trace activity, which is displayed in the Bot Framework Emulator.
                    await turnContext.TraceActivityAsync(
                        "OnTurnError Trace",
                        exception.Message,
                        "https://www.botframework.com/schemas/error",
                        "TurnError");
                };
            }
        }
    

Wenn der App-Benutzer die Anwendung zum ersten Mal verwendet und die Zustimmung des Benutzers erforderlich ist, wird das folgende Dialogfeld angezeigt:

Zustimmungsdialogfeld für Bot-SSO

Wenn der Benutzer Weiter auswählt, tritt eines der folgenden Ereignisse auf:

  • Wenn die Bot-Benutzeroberfläche über eine Anmeldeschaltfläche verfügt, wird der Anmeldeflow für Bots aktiviert. Sie können die Berechtigungen bestimmen, für die die Zustimmung des App-Benutzers erforderlich ist. Verwenden Sie diesen Ansatz, wenn Ihre App andere Graph-Berechtigungen als openidbenötigt.

  • Wenn der Bot keine Anmeldeschaltfläche auf dem OAuth-Karte hat, ist die Zustimmung des App-Benutzers für einen minimalen Berechtigungssatz erforderlich. Dieses Token ist nützlich für die Standardauthentifizierung und zum Abrufen der E-Mail-Adresse des App-Benutzers.

Das angezeigte Zustimmungsdialogfeld gilt für Open-ID-Bereiche, die in Microsoft Entra ID definiert sind. Der App-Benutzer muss seine Zustimmung nur einmal erteilen. Nach der Zustimmung kann der App-Benutzer auf Ihre Bot-App zugreifen und diese für die erteilten Berechtigungen und Bereiche verwenden.

Hinweis

Nachdem der App-Benutzer seine Zustimmung erteilt hat, muss er keine weiteren Berechtigungen mehr erteilen. Wenn die in Microsoft Entra Bereich definierten Berechtigungen geändert werden, muss der App-Benutzer möglicherweise erneut zustimmen. Wenn die Zustimmungsaufforderung dem App-Benutzer jedoch den Zugriff nicht ermöglicht, greift die Bot-App auf die Anmelde-Karte zurück.

Wichtig

Szenarien, in denen keine Zustimmungsdialogfelder erforderlich sind:

  • Wenn der Mandantenadministrator die Zustimmung im Namen des Mandanten erteilt hat, müssen App-Benutzer überhaupt nicht zur Zustimmung aufgefordert werden. Dies bedeutet, dass die App-Benutzer die Zustimmungsdialoge nicht sehen und nahtlos auf die App zugreifen können.
  • Wenn Ihre Microsoft Entra-App in demselben Mandanten registriert ist, von dem Aus Sie eine Authentifizierung in Teams anfordern, kann der App-Benutzer nicht zur Zustimmung aufgefordert werden und erhält sofort ein Zugriffstoken. App-Benutzer stimmen diesen Berechtigungen nur zu, wenn die Microsoft Entra App in einem anderen Mandanten registriert ist.

Wenn Fehler auftreten, lesen Sie Problembehandlung bei der SSO-Authentifizierung in Teams.

Hinzufügen von Code zum Empfangen des Tokens

Die Antwort mit dem Token wird über eine Aufrufaktivität mit demselben Schema gesendet wie andere Aufrufaktivitäten, die die Bots heute erhalten. Der einzige Unterschied ist der Aufrufname, die Anmeldung/tokenExchange und das Wertfeld . Das Feld Wert enthält die ID, eine Zeichenfolge der ursprünglichen Anforderung zum Abrufen des Tokens, und das Feld Token, einen Zeichenfolgenwert, der das Token enthält.

Verwenden Sie den folgenden Codeausschnitt, um die Antwort aufzurufen:

public MainDialog(IConfiguration configuration, ILogger<MainDialog> logger)
            : base(nameof(MainDialog), configuration["ConnectionName"])
        {
            AddDialog(new OAuthPrompt(
                nameof(OAuthPrompt),
                new OAuthPromptSettings
                {
                    ConnectionName = ConnectionName,
                    Text = "Please Sign In",
                    Title = "Sign In",
                    Timeout = 300000, // User has 5 minutes to login (1000 * 60 * 5)
                    EndOnInvalidMessage = true
                }));

            AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));

            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
            {
                PromptStepAsync,
                LoginStepAsync,
            }));

            // The initial child Dialog to run.
            InitialDialogId = nameof(WaterfallDialog);
        }


private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
        }

private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {

            var tokenResponse = (TokenResponse)stepContext.Result;
            if (tokenResponse?.Token != null)
            {
                var token = tokenResponse.Token;

                // On successful login, the token contains sign in token.
            }
            else 
            {
                await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);
            }            

            return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
        }

Hinweis

Die Codeausschnitte verwenden den Wasserfalldialog. Weitere Informationen finden Sie unter Informationen zu Komponenten- und Wasserfalldialogen.

Überprüfen des Zugriffstokens

Web-APIs auf Ihrem Server müssen das Zugriffstoken decodieren und überprüfen, ob es vom Client gesendet wird.

Hinweis

Wenn Sie Bot Framework verwenden, übernimmt es die Überprüfung des Zugriffstokens. Wenn Sie Bot Framework nicht verwenden, befolgen Sie die Richtlinien in diesem Abschnitt.

Weitere Informationen zum Überprüfen des Zugriffstokens finden Sie unter Überprüfen von Token.

Es gibt eine Reihe von Bibliotheken, welche die JWT-Überprüfung verarbeiten können. Die grundlegende Überprüfung umfasst:

  • Überprüfen, ob das Token wohlgeformt ist.
  • Überprüfen, ob das Token von der beabsichtigten Autorität ausgestellt wurde.
  • Überprüfen, ob das Token für die Web-API verwendet wird.

Beachten Sie bei der Überprüfung des Tokens die folgenden Richtlinien:

  • Gültige SSO-Token werden von Microsoft Entra ID ausgestellt. Der iss Anspruch im Token muss mit diesem Wert beginnen.
  • Der Parameter des aud1 Tokens wird auf die App-ID festgelegt, die während Microsoft Entra App-Registrierung generiert wurde.
  • Der Parameter des scp Tokens ist auf access_as_userfestgelegt.

Beispielzugriffstoken

Der folgende Codeausschnitt ist eine typische decodierte Nutzlast eines Zugriffstokens:

{
    aud: "2c3caa80-93f9-425e-8b85-0745f50c0d24",
    iss: "https://login.microsoftonline.com/fec4f964-8bc9-4fac-b972-1c1da35adbcd/v2.0",
    iat: 1521143967,
    nbf: 1521143967,
    exp: 1521147867,
    aio: "ATQAy/8GAAAA0agfnU4DTJUlEqGLisMtBk5q6z+6DB+sgiRjB/Ni73q83y0B86yBHU/WFJnlMQJ8",
    azp: "e4590ed6-62b3-5102-beff-bad2292ab01c",
    azpacr: "0",
    e_exp: 262800,
    name: "Mila Nikolova",
    oid: "6467882c-fdfd-4354-a1ed-4e13f064be25",
    preferred_username: "milan@contoso.com",
    scp: "access_as_user",
    sub: "XkjgWjdmaZ-_xDmhgN1BMP2vL2YOfeVxfPT_o8GRWaw",
    tid: "fec4f964-8bc9-4fac-b972-1c1da35adbcd",
    uti: "MICAQyhrH02ov54bCtIDAA",
    ver: "2.0"
}

Behandeln der Abmeldung von App-Benutzern

Verwenden Sie den folgenden Codeausschnitt, um das Zugriffstoken für den Fall zu verarbeiten, dass sich der App-Benutzer abmeldet:

    private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, 
    CancellationToken cancellationToken = default(CancellationToken))
        {
            if (innerDc.Context.Activity.Type == ActivityTypes.Message)
            {
                var text = innerDc.Context.Activity.Text.ToLowerInvariant();

                // Allow logout anywhere in the command.
                if (text.IndexOf("logout") >= 0)
                {
                    // The UserTokenClient encapsulates the authentication processes.
                    var userTokenClient = innerDc.Context.TurnState.Get<UserTokenClient>();
                    await userTokenClient.SignOutUserAsync(
                    innerDc.Context.Activity.From.Id, 
                    ConnectionName, 
                    innerDc.Context.Activity.ChannelId, 
                    cancellationToken
                    ).ConfigureAwait(false);

                    await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken);
                    return await innerDc.CancelAllDialogsAsync(cancellationToken);
                }
            }

            return null;
        }

Codebeispiel

Beispielname Beschreibung C# Node.js
Bot Conversation SSO – Schnellstart Dieser Beispielcode zeigt die ersten Schritte mit SSO in einem Bot für Microsoft Teams. View View

Hinweis

OnTeamsMessagingExtensionQueryAsync und OnTeamsAppBasedLinkQueryAsync aus der TeamsMessagingExtensionsSearchAuthConfigBot.cs Datei sind die einzigen SSO-Handler, die unterstützt werden. Andere SSO-Handler werden nicht unterstützt.

In diesem Abschnitt werden folgende Themen behandelt:

  1. Aktualisieren von Entwicklungsumgebungsvariablen
  2. Hinzufügen von Code zum Anfordern eines Tokens
  3. Hinzufügen von Code zum Empfangen des Tokens
  4. Hinzufügen eines Tokens zum Bot Framework-Tokenspeicher
  5. Behandeln der Abmeldung von App-Benutzern

Aktualisieren von Entwicklungsumgebungsvariablen

Sie haben den geheimen Clientschlüssel und die OAuth-Verbindungseinstellung für die App in Microsoft Entra-ID konfiguriert. Sie müssen Ihren App-Code mit diesen Variablen konfigurieren.

So aktualisieren Sie die Entwicklungsumgebungsvariablen:

  1. Öffnen Sie das App-Projekt.

  2. Öffnen Sie die ./env Datei für Ihr Projekt.

  3. Aktualisieren Sie die folgenden Variablen:

    • Aktualisieren MicrosoftAppIdSie für die Botregistrierungs-ID von Microsoft Entra-ID.
    • Aktualisieren Sie für MicrosoftAppPasswordden geheimen Clientschlüssel für die Botregistrierung.
    • ConnectionNameAktualisieren Sie für den Namen der OAuth-Verbindung, die Sie in Microsoft Entra ID konfiguriert haben.
    • Aktualisieren MicrosoftAppTenantIdSie für die Mandanten-ID.
  4. Speichern Sie die Datei.

Sie haben nun die erforderlichen Umgebungsvariablen für Ihre Bot-App und SSO konfiguriert. Fügen Sie als Nächstes den Code für die Verarbeitung von Token hinzu.

Hinzufügen von Code zum Anfordern eines Tokens

Die Anforderung zum Abrufen des Tokens ist eine POST-Nachrichtenanforderung, die das vorhandene Nachrichtenschema verwendet. Es ist in den Anhängen einer OAuthCard enthalten. Das Schema für die OAuthCard-Klasse ist in Microsoft Bot Schema 4.0 definiert. Teams aktualisiert das Token, wenn die TokenExchangeResource Eigenschaft auf dem Karte aufgefüllt wird. Für den Teams-Kanal wird nur die Eigenschaft Id berücksichtigt, die eine Tokenanforderung eindeutig identifiziert.

Hinweis

Das Microsoft Bot Framework OAuthPrompt oder MultiProviderAuthDialog wird für die SSO-Authentifizierung unterstützt.

So aktualisieren Sie den Code Ihrer App:

  1. Fügen Sie Codeausschnitt für TeamsSSOTokenExchangeMiddlewarehinzu.

    Fügen Sie den folgenden Codeausschnitt zu AdapterWithErrorHandler.cs (oder der entsprechenden Klasse im Code Ihrer App) hinzu:

    base.Use(new TeamsSSOTokenExchangeMiddleware(storage, configuration["ConnectionName"]));
    

    Hinweis

    Sie erhalten möglicherweise mehrere Antworten für eine bestimmte Anfrage, wenn der Benutzer mehrere aktive Endpunkte hat. Sie müssen alle doppelten oder redundanten Antworten mit dem Token entfernen. Weitere Informationen zu signin/tokenExchange finden Sie unter TeamsSSOTokenExchangeMiddleware-Klasse.

  2. Verwenden Sie den folgenden Codeausschnitt, um ein Token anzufordern.

    Nachdem Sie hinzugefügt haben AdapterWithErrorHandler.cs, muss der folgende Code angezeigt werden:

        public class AdapterWithErrorHandler : CloudAdapter
        {
            public AdapterWithErrorHandler(
                IConfiguration configuration,
                IHttpClientFactory httpClientFactory,
                ILogger<IBotFrameworkHttpAdapter> logger,
                IStorage storage,
                ConversationState conversationState)
                : base(configuration, httpClientFactory, logger)
            {
                base.Use(new TeamsSSOTokenExchangeMiddleware(storage, configuration["ConnectionName"]));
    
                OnTurnError = async (turnContext, exception) =>
                {
                    // Log any leaked exception from the application.
                    // NOTE: In production environment, you must consider logging this to
                    // Azure Application Insights. Visit https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-telemetry?view=azure-bot-service-4.0&tabs=csharp to see how
                    // to add telemetry capture to your bot.
                    logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");
    
                    // Send a message to the user.
                    await turnContext.SendActivityAsync("The bot encountered an error or bug.");
                    await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");
    
                    if (conversationState != null)
                    {
                        try
                        {
                            // Delete the conversationState for the current conversation to prevent the
                            // bot from getting stuck in an error-loop caused by being in a bad state.
                            // ConversationState must be thought of as similar to "cookie-state" in a Web pages.
                            await conversationState.DeleteAsync(turnContext);
                        }
                        catch (Exception e)
                        {
                            logger.LogError(e, $"Exception caught on attempting to Delete ConversationState : {e.Message}");
                        }
                    }
    
                    // Send a trace activity, which will be displayed in the Bot Framework Emulator.
                    await turnContext.TraceActivityAsync(
                        "OnTurnError Trace",
                        exception.Message,
                        "https://www.botframework.com/schemas/error",
                        "TurnError");
                };
            }
        }
    

Wenn der App-Benutzer Ihre App zum ersten Mal verwendet, muss er der SSO-Authentifizierung zustimmen.

SSO-Authentifizierung für die Nachrichtenerweiterungs-App

Wenn der App-Benutzer den Benutzernamen auswählt, wird die Berechtigung erteilt, und er kann die App verwenden.

SSO-Authentifizierung für die Nachrichtenerweiterungs-App abgeschlossen

Das angezeigte Zustimmungsdialogfeld gilt für Open-ID-Bereiche, die in Microsoft Entra ID definiert sind. Der App-Benutzer muss seine Zustimmung nur einmal erteilen. Nach der Zustimmung kann der App-Benutzer auf Ihre Nachrichtenerweiterungs-App zugreifen und diese für die erteilten Berechtigungen und Bereiche verwenden.

Wichtig

Szenarien, in denen keine Zustimmungsdialogfelder erforderlich sind:

  • Wenn der Mandantenadministrator die Zustimmung im Namen des Mandanten erteilt hat, müssen App-Benutzer überhaupt nicht zur Zustimmung aufgefordert werden. Dies bedeutet, dass die App-Benutzer die Zustimmungsdialoge nicht sehen und nahtlos auf die App zugreifen können.

Wenn Fehler auftreten, lesen Sie Problembehandlung bei der SSO-Authentifizierung in Teams.

Hinzufügen von Code zum Empfangen des Tokens

Die Antwort mit dem Token wird über eine Aufrufaktivität mit demselben Schema gesendet wie andere Aufrufaktivitäten, die die Bots heute erhalten. Der einzige Unterschied ist der Aufrufname, die Anmeldung/tokenExchange und das Wertfeld . Das Feld Wert enthält die ID, eine Zeichenfolge der ursprünglichen Anforderung zum Abrufen des Tokens, und das Feld Token, einen Zeichenfolgenwert, der das Token enthält.

Verwenden Sie das folgende Codeausschnittbeispiel, um die Antwort aufzurufen:

public MainDialog(IConfiguration configuration, ILogger<MainDialog> logger)
            : base(nameof(MainDialog), configuration["ConnectionName"])
        {
            AddDialog(new OAuthPrompt(
                nameof(OAuthPrompt),
                new OAuthPromptSettings
                {
                    ConnectionName = ConnectionName,
                    Text = "Please Sign In",
                    Title = "Sign In",
                    Timeout = 300000, // User has 5 minutes to login (1000 * 60 * 5)
                    EndOnInvalidMessage = true
                }));

            AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));

            AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
            {
                PromptStepAsync,
                LoginStepAsync,
            }));

            // The initial child Dialog to run.
            InitialDialogId = nameof(WaterfallDialog);
        }


private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
        }

private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            
            var tokenResponse = (TokenResponse)stepContext.Result;
            if (tokenResponse?.Token != null)
            {
                var token = tokenResponse.Token;

                // On successful login, the token contains sign in token.
            }
            else 
            {
                await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);
            }            

            return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
        }

Hinweis

Die Codeausschnitte verwenden den Wasserfalldialog-Bot. Weitere Informationen zum Wasserfalldialog finden Sie unter Informationen zu Komponenten- und Wasserfalldialogen.

Sie erhalten das Token im OnTeamsMessagingExtensionQueryAsync Handler in der turnContext.Activity.Value Nutzlast oder im OnTeamsAppBasedLinkQueryAsync, je nachdem, für welches Szenario Sie einmaliges Anmelden aktivieren.

JObject valueObject=JObject.FromObject(turnContext.Activity.Value);
if(valueObject["authentication"] !=null)
 {
    JObject authenticationObject=JObject.FromObject(valueObject["authentication"]);
    if(authenticationObject["token"] !=null)
 }

Überprüfen des Zugriffstokens

Web-APIs auf Ihrem Server müssen das Zugriffstoken decodieren und überprüfen, ob es vom Client gesendet wird.

Hinweis

Wenn Sie Bot Framework verwenden, übernimmt es die Überprüfung des Zugriffstokens. Wenn Sie Bot Framework nicht verwenden, befolgen Sie die Richtlinien in diesem Abschnitt.

Weitere Informationen zum Überprüfen des Zugriffstokens finden Sie unter Überprüfen von Token.

Es gibt eine Reihe von Bibliotheken, welche die JWT-Überprüfung verarbeiten können. Die grundlegende Überprüfung umfasst:

  • Überprüfen, ob das Token wohlgeformt ist.
  • Überprüfen, ob das Token von der beabsichtigten Autorität ausgestellt wurde.
  • Überprüfen, ob das Token für die Web-API verwendet wird.

Beachten Sie bei der Überprüfung des Tokens die folgenden Richtlinien:

  • Gültige SSO-Token werden von Microsoft Entra ID ausgestellt. Der iss Anspruch im Token muss mit diesem Wert beginnen.
  • Der Parameter des aud1 Tokens wird auf die App-ID festgelegt, die während Microsoft Entra App-Registrierung generiert wurde.
  • Der Parameter des scp Tokens ist auf access_as_userfestgelegt.

Beispielzugriffstoken

Der folgende Codeausschnitt ist eine typische decodierte Nutzlast eines Zugriffstokens:

{
    aud: "2c3caa80-93f9-425e-8b85-0745f50c0d24",
    iss: "https://login.microsoftonline.com/fec4f964-8bc9-4fac-b972-1c1da35adbcd/v2.0",
    iat: 1521143967,
    nbf: 1521143967,
    exp: 1521147867,
    aio: "ATQAy/8GAAAA0agfnU4DTJUlEqGLisMtBk5q6z+6DB+sgiRjB/Ni73q83y0B86yBHU/WFJnlMQJ8",
    azp: "e4590ed6-62b3-5102-beff-bad2292ab01c",
    azpacr: "0",
    e_exp: 262800,
    name: "Mila Nikolova",
    oid: "6467882c-fdfd-4354-a1ed-4e13f064be25",
    preferred_username: "milan@contoso.com",
    scp: "access_as_user",
    sub: "XkjgWjdmaZ-_xDmhgN1BMP2vL2YOfeVxfPT_o8GRWaw",
    tid: "fec4f964-8bc9-4fac-b972-1c1da35adbcd",
    uti: "MICAQyhrH02ov54bCtIDAA",
    ver: "2.0"
}

Hinzufügen eines Tokens zum Bot Framework-Tokenspeicher

Wenn Sie die OAuth-Verbindung verwenden, müssen Sie das Token im Bot Framework-Tokenspeicher aktualisieren oder hinzufügen. Fügen Sie das folgende Codeausschnittbeispiel zu (oder der entsprechenden Datei im Code Ihrer App) hinzu, um TeamsMessagingExtensionsSearchAuthConfigBot.cs das Token im Store zu aktualisieren oder hinzuzufügen:

Hinweis

Sie finden das Beispiel TeamsMessagingExtensionsSearchAuthConfigBot.cs unter Tab, Bot, and Message Extension (ME) SSO.

protected override async Task<InvokeResponse> OnInvokeActivityAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
     {
         JObject valueObject = JObject.FromObject(turnContext.Activity.Value);
         if (valueObject["authentication"] != null)
         {
             JObject authenticationObject = JObject.FromObject(valueObject["authentication"]);
             if (authenticationObject["token"] != null)
             {
                 //If the token is NOT exchangeable, then return 412 to require user consent.
                 if (await TokenIsExchangeable(turnContext, cancellationToken))
                 {
                     return await base.OnInvokeActivityAsync(turnContext, cancellationToken).ConfigureAwait(false);
                 }
                 else
                 {
                     var response = new InvokeResponse();
                     response.Status = 412;
                     return response;
                 }
             }
         }
         return await base.OnInvokeActivityAsync(turnContext, cancellationToken).ConfigureAwait(false);
     }
     private async Task<bool> TokenIsExchangeable(ITurnContext turnContext, CancellationToken cancellationToken)
     {
         TokenResponse tokenExchangeResponse = null;
         try
         {
             JObject valueObject = JObject.FromObject(turnContext.Activity.Value);
             var tokenExchangeRequest =
             ((JObject)valueObject["authentication"])?.ToObject<TokenExchangeInvokeRequest>();
             var userTokenClient = turnContext.TurnState.Get<UserTokenClient>();
             tokenExchangeResponse = await userTokenClient.ExchangeTokenAsync(
                             turnContext.Activity.From.Id,
                              _connectionName,
                              turnContext.Activity.ChannelId,
                              new TokenExchangeRequest
              {
                  Token = tokenExchangeRequest.Token,
              },
               cancellationToken).ConfigureAwait(false);
         }
 #pragma warning disable CA1031 //Do not catch general exception types (ignoring, see comment below)
         catch
 #pragma warning restore CA1031 //Do not catch general exception types
         {
             //ignore exceptions.
             //if token exchange failed for any reason, tokenExchangeResponse above remains null, and a failure invoke response is sent to the caller.
             //This ensures the caller knows that the invoke has failed.
         }
         if (tokenExchangeResponse == null || string.IsNullOrEmpty(tokenExchangeResponse.Token))
         {
             return false;
         }
         return true;
     }

Behandeln der Abmeldung von App-Benutzern

Verwenden Sie den folgenden Codeausschnitt, um das Zugriffstoken für den Fall zu verarbeiten, dass sich der App-Benutzer abmeldet:

    private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, 
    CancellationToken cancellationToken = default(CancellationToken))
        {
            if (innerDc.Context.Activity.Type == ActivityTypes.Message)
            {
                var text = innerDc.Context.Activity.Text.ToLowerInvariant();

                // Allow logout anywhere in the command.
                if (text.IndexOf("logout") >= 0)
                {
                    // The UserTokenClient encapsulates the authentication processes.
                    var userTokenClient = innerDc.Context.TurnState.Get<UserTokenClient>();
                    await userTokenClient.SignOutUserAsync(
    innerDc.Context.Activity.From.Id, 
    ConnectionName, 
    innerDc.Context.Activity.ChannelId, 
    cancellationToken
    ).ConfigureAwait(false);

                    await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken);
                    return await innerDc.CancelAllDialogsAsync(cancellationToken);
                }
            }

            return null;
        }

Codebeispiel

Dieser Abschnitt enthält ein Beispiel für das Sdk für die Botauthentifizierung v3.

Beispielname Beschreibung .NET Node.js Python Manifest
Botauthentifizierung In diesem Beispiel wird gezeigt, wie Sie mit der Authentifizierung in einem Bot für Teams beginnen. View View View View
Tab-, Bot- und Nachrichtenerweiterung (ME) SSO Dieses Beispiel zeigt SSO für Registerkarten-, Bot- und Nachrichtenerweiterung – Suche, Aktion, Link unfurl. View Anzeigen Anzeigen
Registerkarten-, Bot- und Nachrichtenerweiterung In diesem Beispiel wird gezeigt, wie Sie die Authentifizierung in Bot, Registerkarte und Nachrichtenerweiterung mit SSO überprüfen. View View Anzeigen

Nächster Schritt