Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Bevor Sie Code zum Aktivieren des einmaligen Anmeldens (Single Sign-On, SSO) hinzufügen, stellen Sie sicher, dass Sie Ihre App- und Bot-Ressource im Microsoft Entra Admin Center konfigurieren.
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 Artikel wird Folgendes behandelt:
- Entwicklungsumgebungsvariablen aktualisieren
- Hinzufügen von Code zum Anfordern eines Tokens
- Fügen Sie Code zum Empfangen des Tokens hinzu
- Token zum Bot Framework-Tokenspeicher hinzufügen
- Abmelden von App-Benutzern behandeln
Entwicklungsumgebungsvariablen aktualisieren
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:
Öffnen Sie das App-Projekt.
Öffnen Sie die
./envDatei für Ihr Projekt.Aktualisieren Sie die folgenden Variablen:
- Aktualisieren
MicrosoftAppIdSie für die Bot-Registrierungs-ID von der Microsoft Entra ID. - Aktualisieren
MicrosoftAppPasswordSie für den geheimen Clientschlüssel für die Bot-Registrierung. - Aktualisieren
ConnectionNameSie für den Namen der OAuth-Verbindung, die Sie in Microsoft Entra ID konfiguriert haben. - Aktualisieren
MicrosoftAppTenantIdSie für die Mandanten-ID.
- Aktualisieren
Speichern Sie die Datei.
Sie haben jetzt 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 unter Verwendung des vorhandenen Nachrichtenschemas. Es ist in den Anhängen einer OAuthCard enthalten. Das Schema für die OAuthCard-Klasse ist im Microsoft Bot-Schema 4.0 definiert. Teams aktualisiert das Token, wenn die TokenExchangeResource Eigenschaft auf der Karte eingetragen ist. 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:
Codeausschnitt für
TeamsSSOTokenExchangeMiddleware.Fügen Sie den folgenden Codeausschnitt zu
AdapterWithErrorHandler.cs(oder die entsprechende 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 eliminieren. Weitere Informationen zu signin/tokenExchange finden Sie unter TeamsSSOTokenExchangeMiddleware-Klasse.
Verwenden Sie den folgenden Codeausschnitt zum Anfordern eines Tokens.
Nachdem Sie den
AdapterWithErrorHandler.cshinzugefügt haben, 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"); }; } }
Zustimmungsdialogfeld zum Abrufen des Zugriffstokens
Wenn der App-Benutzer Ihre App zum ersten Mal verwendet, muss er der SSO-Authentifizierung zustimmen.
Wenn der App-Benutzer den Benutzernamen auswählt, wird die Berechtigung erteilt, und er kann die App verwenden.
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 Ihrer Zustimmung kann der App-Benutzer für die erteilten Berechtigungen und Bereiche auf Ihre Nachrichtenerweiterungs-App zugreifen und diese verwenden.
Wichtig
Szenarien, in denen keine Zustimmungsdialogfelder erforderlich sind:
- Wenn der Administrator die Zustimmung im Namen des Mandanten erteilt hat, müssen App-Benutzer überhaupt nicht zur Zustimmung aufgefordert werden. Dies bedeutet, dass den App-Benutzern die Zustimmungsdialoge nicht angezeigt werden und sie nahtlos auf die App zugreifen können.
Wenn Fehler auftreten, lesen Sie Problembehandlung für die SSO-Authentifizierung in Teams.
Fügen Sie Code zum Empfangen des Tokens hinzu
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 besteht im Aufrufnamen, sign-in/tokenExchange und im 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 Wasserfall-Dialogbot. Weitere Informationen zum Wasserfalldialogfeld 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 SSO aktivieren.
JObject valueObject = JObject.FromObject(turnContext.Activity.Value);
if (valueObject["authentication"] != null)
{
JObject authenticationObject = JObject.FromObject(valueObject["authentication"]);
if (authenticationObject["token"] != null)
{
// Process the token.
}
}
Ü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 von Zugriffstoken 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 vorgesehenen Behörde ausgestellt wurde.
- Überprüfen, ob das Token für die Web-API vorgesehen ist.
Beachten Sie bei der Überprüfung des Tokens die folgenden Richtlinien:
- Gültige SSO-Token werden von Microsoft Entra ID ausgestellt. Der
issAnspruch im Token muss mit diesem Wert beginnen. - Der Parameter des
aud1Tokens wird auf die App-ID festgelegt, die während der Registrierung der Microsoft Entra-App generiert wird. - Der Parameter des
scpTokens ist aufaccess_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"
}
Token zum Bot Framework-Tokenspeicher hinzufügen
Wenn Sie die OAuth-Verbindung verwenden, müssen Sie das Token im Bot Framework Token-Speicher aktualisieren oder hinzufügen. Fügen Sie das folgende Codeausschnittbeispiel (oder die entsprechende Datei im Code Ihrer App) hinzu, TeamsMessagingExtensionsSearchAuthConfigBot.cs um das Token im Store zu aktualisieren oder hinzuzufügen:
Hinweis
Sie finden das Beispiel TeamsMessagingExtensionsSearchAuthConfigBot.cs in Registerkarten-, Bot- und Nachrichtenerweiterung (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);
}
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 fails for any reason,
// tokenExchangeResponse remains null and a failure invoke response is sent.
}
if (tokenExchangeResponse == null || string.IsNullOrEmpty(tokenExchangeResponse.Token))
{
return false;
}
return true;
}
Abmelden von App-Benutzern behandeln
Verwenden Sie den folgenden Codeausschnitt, um das Zugriffstoken zu behandeln, falls 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 Beispiele für das Bot Authentication v3 SDK.
| Beispielname | Beschreibung | .NET | Node.js | Python | Manifest |
|---|---|---|---|---|---|
| Robot-Authentifizierung | Diese Beispiel-App zeigt, wie ein Bot die Teams-Authentifizierung verwenden kann. | View | View | View | – |
| Registerkarten-, Bot- und Nachrichtenerweiterungs-SSO | Diese Beispiel-App veranschaulicht die SSO-Integration von Teams für Registerkarten, Bots und Nachrichtenerweiterungen mit C# und Microsoft Entra ID für eine sichere Authentifizierung. | View | View | – | View |
| Registerkarten-, Bot- und Nachrichtenerweiterung | Dieses Beispiel zeigt die Microsoft Entra ID- und Facebook-Authentifizierung über Bots, Registerkarten und Nachrichtenerweiterungen in Microsoft Teams hinweg. | View | View | – | View |