Hinzufügen von Single Sign-On zu einem Bot
GILT FÜR: SDK v4
In diesem Artikel wird erläutert, wie Sie das SSO-Feature (Single Sign-On, einmaliges Anmelden) in einem Bot verwenden. Dazu verwendet dieses Feature einen Consumer-Bot, der auch als Stamm- oder übergeordneter Bot bezeichnet wird, um mit einem Skill- oder untergeordneten Bot zu interagieren. Im vorliegenden Artikel werden die Begriffe Root-Bot und Skill-Bot verwendet.
Wenn Sie SSO-Unterstützung einschließen, kann sich ein Benutzer mit einem Identitätsanbieter beim Stamm-Bot anmelden und muss sich nicht erneut anmelden, wenn die Steuerung an einen Skill übergeben wird.
Die Root- und Skill-Bots sind separate Bots, die auf unterschiedlichen Servern ausgeführt werden können und jeweils über einen separaten Arbeitsspeicher und einen eigenen Zustand verfügen. Weitere Informationen finden Sie unter Übersicht über Skills und Einen Skill implementieren. Weitere Informationen zur Benutzerauthentifizierung finden Sie unter Bot Framework-Authentifizierungsgrundlagen, Benutzerauthentifizierung und Hinzufügen der Authentifizierung zu einem Bot.
Wichtig
Wenn Sie die Azure KI Bot Service-Authentifizierung mit Webchat verwenden, müssen einige wichtige Sicherheitsaspekte beachtet werden. Weitere Informationen finden Sie im Abschnitt Sicherheitshinweise des Artikels zur REST-Authentifizierung.
Voraussetzungen
- Kenntnisse über Bot-Grundlagen, Verwalten des Zustands und Über Single Sign-On.
- Kenntnisse der Dialogbibliothek und der Implementierung eines sequentiellen Konversationsablaufs und der Wiederverwendung von Dialogen
- Erfahrung mit Azure- und OAuth 2.0-Entwicklung
- Mindestens Visual Studio 2019 für .NET.
- Das SSO mit Simple Skill Consumer und Skill in C#.
Über das Beispiel
Dieser Artikel bezieht sich auf zwei Bots: RootBot und SkillBot. Der RootBot leitet Aktivitäten an den SkillBot weiter. Zusammen modellieren sie dieses typische Skillszenario:
- Ein Root-Bot ruft einen oder mehrere Skillbots auf.
- Root- und Skillbots implementieren die im Artikel Hinzufügen von Authentifizierung zu einem Bot beschriebene Standardauthentifizierung.
- Ein Benutzer meldet sich beim Rootbot an.
- Da der Benutzer bereits beim Rootbot angemeldet und das einmalige Anmelden aktiviert ist, erfolgt die Anmeldung beim Skillbot ohne weitere Benutzerinteraktion.
Eine Übersicht über die Authentifizierung durch das Bot Framework finden Sie unter Bot-Authentifizierung. Hintergrundinformationen zu SSO finden Sie unter Single Sign-On.
Der RootBot unterstützt SSO. Er kommuniziert im Namen des Benutzers mit dem SkillBot, ohne dass der Benutzer sich erneut beim _SkillBot authentifizieren muss.
Für jedes Projekt im Beispiel benötigen Sie Folgendes:
- Eine Microsoft-Entra-ID-Anwendung zur Registrierung einer Bot-Ressource in Azure.
- Eine Identitätsanbieteranwendung von Microsoft Entra ID für die Authentifizierung.
Hinweis
Aktuell wird nur der Identitätsanbieter Microsoft Entra ID unterstützt.
Erstellen der Azure-RootBot-Ressource
- Erstellen Sie eine Azure-Bot-Ressource im Azure-Portal für das
RootBot
. Führen Sie die unter Erstellen einer Azure-Bot-Ressource beschriebenen Schritte aus. - Kopieren und speichern Sie die App-ID und den geheimen Clientschlüssel der Botregistrierung.
Erstellen der Microsoft-Entra-ID-Identität für RootBot
Die Microsoft Entra ID ist ein Cloudidentitätsdienst, der die Erstellung von Anwendungen zur sicheren Benutzeranmeldung über branchenübliche Protokolle wie OAuth 2.0 ermöglicht.
Erstellen Sie eine Identitätsanwendung für den
RootBot
, der Microsoft Entra ID zum Authentifizieren des Benutzers verwendet. Führen Sie die unter Erstellen des Microsoft-Entra-ID-Identitätsanbieters beschriebenen Schritte aus.Wählen Sie im linken Bereich die Option Manifest aus.
Legen Sie
accessTokenAcceptedVersion
auf 2 fest.Wählen Sie Speichern.
Wählen Sie im linken Bereich Ein API sichtbar machen aus.
Wählen Sie im rechten Bereich Einen Bereich hinzufügen aus.
Klicken Sie im Abschnitt Bereich hinzufügen ganz rechts auf Speichern und fortfahren.
Wählen Sie im angezeigten Fenster unter Wer kann einwilligen? die Option Administratoren und Benutzer aus.
Geben Sie die verbleibenden erforderlichen Informationen ein.
Wählen Sie Bereich hinzufügen aus.
Kopieren und speichern Sie den Bereichswert.
Erstellen einer OAuth-Verbindungseinstellung für RootBot
Erstellen Sie eine Microsoft-Entra-ID-Verbindung in der
RootBot
-Botregistrierung und geben Sie die unter Microsoft Entra ID beschriebenen Werte sowie den unten angegebenen Wert ein.Lassen Sie das Feld für die URL für den Tokenaustausch leer.
Geben Sie im Feld Bereich den Bereichswert für
RootBot
ein, den Sie in einem vorherigen Schritt gespeichert haben.Hinweis
Bereiche enthalten die URL, die der Benutzer anfänglich beim Stamm-Bot anmeldet, während die Tokenaustausch-URL leer bleibt.
Nehmen wir beispielsweise an, dass der Stamm-Bot Appid rootAppId ist und der Skill-Bot appid skillAppId ist. Die Bereiche des Stamm-Bots sehen wie api://rootAppId/customScope aus, die zum Anmelden des Benutzers verwendet werden. Die Bereiche dieses Stamm-Bots werden dann während des SSO mit api://skillAppId/customscope ausgetauscht.
Kopieren und speichern Sie den Namen der Verbindung.
Erstellen der Azure-SkillBot-Ressource
- Erstellen Sie eine Azure-Bot-Ressource im Azure-Portal für das
SkillBot
. Führen Sie die unter Erstellen einer Azure-Bot-Ressource beschriebenen Schritte aus. - Kopieren und speichern Sie die App-ID und den geheimen Clientschlüssel der Botregistrierung.
Erstellen der Microsoft-Entra-ID-Identität für SkillBot
Die Microsoft Entra ID ist ein Cloudidentitätsdienst, der die Erstellung von Anwendungen zur sicheren Benutzeranmeldung über branchenübliche Protokolle wie OAuth 2.0 ermöglicht.
Erstellen Sie eine Identitätsanwendung für den
SkillBot
, der Microsoft Entra ID zum Authentifizieren des Bots verwendet. Führen Sie die unter Erstellen des Microsoft-Entra-ID-Identitätsanbieters beschriebenen Schritte aus.Wählen Sie im linken Bereich die Option Manifest aus.
Legen Sie
accessTokenAcceptedVersion
auf 2 fest.Wählen Sie Speichern.
Wählen Sie im linken Bereich Ein API sichtbar machen aus.
Wählen Sie im rechten Bereich Einen Bereich hinzufügen aus.
Klicken Sie im Abschnitt Bereich hinzufügen ganz rechts auf Speichern und fortfahren.
Wählen Sie im angezeigten Fenster unter Zum Einwilligen berechtigte Personen die Option Administratoren und Benutzer aus.
Geben Sie die verbleibenden erforderlichen Informationen ein.
Wählen Sie Bereich hinzufügen aus.
Kopieren und speichern Sie den Bereichswert.
Wählen Sie Client-Anwendung hinzufügen. Geben Sie im Abschnitt ganz rechts im Feld Client-ID die App-ID der RootBot-Identität ein, die Sie zuvor gespeichert haben. Stellen Sie sicher, dass Sie die App-ID der RootBot-Identität verwenden, nicht die App-ID der Registrierung.
Hinweis
Für Clientanwendungen unterstützt der Azure KI Bot Service keine einmaliges Sing-On mit dem B2C-Identitätsanbieter von Microsoft Entra ID.
Aktivieren Sie unter Autorisierter Bereich das Kontrollkästchen neben dem Bereichswert.
Wählen Sie Anwendung hinzufügen aus.
Wählen Sie im linken Navigationsbereich API-Berechtigungen aus. Dies ist eine bewährte Methode, um die API-Berechtigungen für die App explizit festzulegen.
Klicken Sie im rechten Bereich auf Eine Berechtigung hinzufügen.
Wählen Sie Microsoft-APIs und dann Microsoft Graph aus.
Wählen Sie Delegierte Berechtigungen aus, und stellen Sie sicher, dass die benötigten Berechtigungen ausgewählt sind. Dieses Beispiel erfordert die unten aufgeführten Berechtigungen.
Hinweis
Bei Berechtigungen, die mit ADMINISTRATOREINWILLIGUNG ERFORDERLICH gekennzeichnet sind, müssen sich sowohl ein Benutzer als auch ein Mandantenadministrator anmelden.
- openid
- profile
- User.Read
- User.ReadBasic.All
Wählen Sie Berechtigungen hinzufügen aus.
Erstellen einer OAuth-Verbindungseinstellung für SkillBot
Erstellen Sie eine Microsoft-Entra-ID-Verbindung in der
SkillBot
-Botregistrierung und geben Sie die unter Microsoft Entra ID beschriebenen Werte sowie die unten angegebenen Werte ein.Geben Sie im Feld URL für den Tokenaustausch den Bereichswert für
SkillBot
ein, den Sie in einem vorherigen Schritt gespeichert haben.Geben Sie im Feld "Bereiche" die folgenden Werte ein, die durch Leerzeichen getrennt sind:
profile
User.Read
User.ReadBasic.All
openid
Kopieren und speichern Sie den Namen der Verbindung in eine Datei.
Testen der Verbindung
- Klicken Sie auf den Verbindungseintrag, um die erstellte Verbindung zu öffnen.
- Klicken Sie oben im Bereich Service Provider Connection Setting (Dienstanbieter-Verbindungseinstellung) auf Verbindung testen.
- Beim ersten Mal sollte dies eine neue Registerkarte im Browser öffnen, auf der die Berechtigungen aufgeführt werden, die die App von Ihnen anfordert.
- Wählen Sie Akzeptieren aus.
- Daraufhin werden Sie zu einer Seite mit dem Hinweis weitergeleitet, dass die Verbindung mit <Name Ihrer Verbindung> erfolgreich getestet wurde.
Weitere Informationen finden Sie unter Microsoft Entra ID für Entwickler (v1.0) – Übersicht und Übersicht über Microsoft Identity Platform (v2.0). Informationen zu den Unterschieden zwischen den Endpunkten der Versionen 1 und 2 finden Sie unter Gründe für eine Aktualisierung auf die Microsoft Identity Platform (v2.0). Vollständige Informationen finden Sie unter Microsoft Identity Platform (früher Microsoft Entra ID für Entwickler).
Vorbereiten des Beispielcodes
Sie müssen die Datei appsettings.json
in beiden Beispielen wie unten beschrieben aktualisieren.
Klonen Sie das Beispiel SSO with Simple Skill Consumer and Skill aus dem GitHub-Repository.
Öffnen Sie die
SkillBot
-Projektdateiappsettings.json
. Weisen Sie die folgenden Werte aus der gespeicherten Datei zu:{ "MicrosoftAppId": "<SkillBot registration app ID>", "MicrosoftAppPassword": "<SkillBot registration password>", "ConnectionName": "<SkillBot connection name>", "AllowedCallers": [ "<RootBot registration app ID>" ] }
Öffnen Sie die
RootBot
-Projektdateiappsettings.json
. Weisen Sie die folgenden Werte aus der gespeicherten Datei zu:{ "MicrosoftAppId": "<RootBot registration app ID>", "MicrosoftAppPassword": "<RootBot registration password>", "ConnectionName": "<RootBot connection name>", "SkillHostEndpoint": "http://localhost:3978/api/skills/", "BotFrameworkSkills": [ { "Id": "SkillBot", "AppId": "<SkillBot registration app ID>", "SkillEndpoint": "http://localhost:39783/api/messages" } ] }
Testen der Beispiele
Verwenden Sie Folgendes für die Tests:
RootBot
-Befehlelogin
ermöglicht dem Benutzer die Anmeldung bei der Microsoft-Entra-ID-Registrierung über denRootBot
. Nach der Anmeldung erfolgt die Anmeldung beimSkillBot
über SSO. Der Benutzer muss sich nicht erneut anmelden.token
zeigt das Benutzertoken an.logout
meldet den Benutzer vomRootBot
ab.
SkillBot
-Befehleskill login
ermöglicht es demRootBot
, sich im Namen des Benutzers beimSkillBot
anzumelden. Wenn der Benutzer bereits angemeldet ist, wird keine Anmeldekarte angezeigt, sofern SSO fehlerfrei funktioniert.skill token
zeigt das Benutzertoken aus demSkillBot
an.skill logout
meldet den Benutzer vomSkillBot
ab.
Hinweis
Wenn ein Benutzer zum ersten Mal SSO in einem Skill verwendet, wird möglicherweise eine OAuth-Karte für die Anmeldung angezeigt. Das liegt daran, dass dieser Benutzer noch keine Zustimmung für die Microsoft-Entra-ID-App des Skills erteilt hat. Um eine solche Situation zu vermeiden, kann die Administratoreinwilligung für alle Graph-Berechtigungen gewährt werden, die von der Microsoft-Entra-ID-App angefordert werden.
Installieren Sie Bot Framework Emulator, sofern noch nicht geschehen. Siehe auch Debuggen mit dem Emulator.
Sie müssen den Emulator für die Bot-Beispielanmeldung so konfigurieren, dass sie funktioniert. Führen Sie die folgenden Schritte aus: Siehe Konfigurieren des Emulators für die Authentifizierung.
Nach dem Konfigurieren des Authentifizierungsmechanismus können Sie die eigentlichen Botbeispieltests durchführen.
Öffnen Sie in Visual Studio die Projektmappe
SSOWithSkills.sln
, und konfigurieren Sie sie zum Starten des Debuggens mit mehreren Prozessen.Starten Sie das Debuggen lokal auf Ihrem Computer. Beachten Sie, dass in der
RootBot
-Projektdateiappsettings.json
die folgenden Einstellungen zur Verfügung stehen:"SkillHostEndpoint": "http://localhost:3978/api/skills/" "SkillEndpoint": "http://localhost:39783/api/messages"
Hinweis
Diese Einstellungen implizieren, dass sowohl der
RootBot
als auch derSkillBot
auf dem lokalen Computer ausgeführt werden. Der Emulator kommuniziert an Port 3978 mit demRootBot
und derRootBot
kommuniziert an Port 39783 mitSkillBot
. Sobald Sie den Debugprozess starten, werden zwei Standardbrowserfenster geöffnet: eins an Port 3978, das andere an Port 39783.Starten Sie den Emulator.
Wenn Sie sich mit dem Bot verbinden, geben Sie Ihre
RootBot
-Registrierungs-App-ID und Ihr Passwort ein.Geben Sie
hi
ein, um die Konversation zu starten.Geben Sie login ein. Der
RootBot
zeigt die Authentifizierungskarte Bei AAD anmelden an.Wählen Sie Anmelden aus. Das Popupdialogfeld Öffnen der URL bestätigen wird angezeigt.
Klicken Sie auf Bestätigen. Sie werden angemeldet und das
RootBot
-Token wird angezeigt.Geben Sie token ein, um das Token erneut anzuzeigen.
Jetzt können Sie mit dem
SkillBot
kommunizieren. Sobald Sie sich über denRootBot
angemeldet haben, müssen Sie Ihre Anmeldeinformationen nur neu eingeben, wenn Sie sich abgemeldet haben. Dies zeigt, dass SSO funktioniert.Geben Sie skill login im Emulatorfeld ein. Sie werden nicht aufgefordert, sich anzumelden. Stattdessen wird das SkillBot-Token angezeigt.
Geben Sie skill token ein, um das Token erneut anzuzeigen.
Jetzt können Sie skill logout eingeben, um sich vom
SkillBot
abzumelden. Geben Sie dann logout ein, um sich vomSimpleRootBoot
abzumelden.
Weitere Informationen
Das folgende Diagramm des zeitlichen Ablaufs gilt für die in diesem Artikel verwendeten Beispiele und zeigt die Interaktion zwischen den verschiedenen beteiligten Komponenten. ABS steht für Azure KI Bot Service.
- Beim ersten Mal gibt der Benutzer den
login
-Befehl für den RootBot ein. - Der RootBot sendet eine OAuthCard, über die der Benutzer aufgefordert wird, sich anzumelden.
- Der Benutzer gibt die Anmeldeinformationen für die Authentifizierung ein, die an den ABS (Azure KI Bot Service) gesendet werden.
- Der ABS sendet das Authentifizierungstoken, das basierend auf den Anmeldeinformationen des Benutzers generiert wurde, an den RootBot.
- Der RootBot zeigt dem Benutzer das Rootbot-Token an.
- Der Benutzer gibt den
skill login
-Befehl für den SkillBot ein. - Der SkillBot sendet eine OAuthCard an den RootBot.
- Der RootBot ruft ein austauschbares Token aus dem ABS ab.
- SSO sendet das SkillBot-Qualifikationstoken an den RootBot.
- Der RootBot zeigt dem Benutzer das Skillbot-Token an. Beachten Sie, dass das Skillbot-Token generiert wurde, ohne dass der Benutzer sich beim SkillBot anmelden musste. Der Grund hierfür ist das Feature des einmaligen Anmeldens (Single Sign-On, SSO).
Das folgende Beispiel zeigt, wie der Tokenaustausch erfolgt. Der Code stammt aus der Datei TokenExchangeSkillHandler.cs.
private async Task<bool> InterceptOAuthCards(ClaimsIdentity claimsIdentity, Activity activity)
{
var oauthCardAttachment = activity.Attachments?.FirstOrDefault(a => a?.ContentType == OAuthCard.ContentType);
if (oauthCardAttachment != null)
{
var targetSkill = GetCallingSkill(claimsIdentity);
if (targetSkill != null)
{
var oauthCard = ((JObject)oauthCardAttachment.Content).ToObject<OAuthCard>();
if (!string.IsNullOrWhiteSpace(oauthCard?.TokenExchangeResource?.Uri))
{
using (var context = new TurnContext(_adapter, activity))
{
context.TurnState.Add<IIdentity>("BotIdentity", claimsIdentity);
// AAD token exchange
try
{
var result = await _tokenExchangeProvider.ExchangeTokenAsync(
context,
_connectionName,
activity.Recipient.Id,
new TokenExchangeRequest() { Uri = oauthCard.TokenExchangeResource.Uri }).ConfigureAwait(false);
if (!string.IsNullOrEmpty(result?.Token))
{
// If token above is null, then SSO has failed and hence we return false.
// If not, send an invoke to the skill with the token.
return await SendTokenExchangeInvokeToSkill(activity, oauthCard.TokenExchangeResource.Id, result.Token, oauthCard.ConnectionName, targetSkill, default).ConfigureAwait(false);
}
}
catch
{
// Show oauth card if token exchange fails.
return false;
}
return false;
}
}
}
}
return false;
}