Freigeben über


Konfigurieren Ihres .NET-Agents für die Verwendung von OAuth

OAuth für einen .NET-Agent wird zuerst in Ihrer Azure Bot-Ressource und der entsprechenden App-Registrierung bereitgestellt. Die Agentlaufzeit erwirbt und aktualisiert dann Benutzertoken für Sie über die AgentApplication automatische Anmeldefunktion. Die automatische Anmeldung kann global (alle Aktivitätstypen) oder selektiv ausgeführt werden, sodass nur bestimmte Routen oder Aktivitätstypen ein Token anfordern.

Sie können mehrere OAuth-Handler in der Konfiguration registrieren und sie bestimmten Routen zuweisen oder einen einzelnen Standardhandler deklarieren, der überall verwendet wird. Jeder Handler kann optional einen On-Behalf-Of (OBO)-Austausch durchführen, wenn die Azure-Seite dafür konfiguriert ist. Einen schnellen Einstieg finden Sie im AutoSignIn-Beispiel, oder stellen Sie die hier gezeigte Konfiguration in einen vorhandenen Agent um.

In den folgenden Abschnitten wird beschrieben, wie Sie UserAuthorization konfigurieren, zwischen einem globalen und einem routenspezifischen Ansatz wählen und Token (Standard und OBO) während der Verarbeitung abrufen. Regionale Anleitungen werden auch für Nicht-US-Bereitstellungen bereitgestellt.

Der .NET-Agent ist in AppSettings konfiguriert oder mit Code in Program.cs. Dieses Dokument enthält Details mithilfe von Appsettings.

Einstellungen

Das UserAuthorization Objekt innerhalb AgentApplication steuert, wie Benutzertoken abgerufen werden. Der folgende JSON-Code zeigt die hierarchische Struktur gefolgt von Tabellen, die jede Eigenschaft für UserAuthorization und für das geschachtelte Settings Objekt beschreiben.

  "AgentApplication": {
    "UserAuthorization": {
      "DefaultHandlerName": "{{handler-name}}",
      "AutoSignIn": true | false,
      "Handlers": {
        "{{handler-name}}": {
          "Settings": {
            "AzureBotOAuthConnectionName": "{{azure-bot-connection-name}}",
            "OBOConnectionName": "{{connection-name}}",
            "OBOScopes": [
              "{{obo-scope}}"
            ],
            "Title": "{{signin-card-title}}",
            "Text": "{{signin-card-button-text}}",
            "InvalidSignInRetryMax": {{int}},
            "InvalidSignInRetryMessage": {{invalid-attempt-message}},
            "Timeout": {{timeout-ms}}
          }
        }
      }
    }
  }

Eigenschaften der Benutzerberechtigungen

In der folgenden Tabelle sind die Eigenschaften der obersten Ebene UserAuthorization aufgeführt, die bestimmen, wie Handler ausgewählt werden und wie Token für jede eingehende Aktivität abgerufen werden.

Eigentum Erforderlich Typ Description
DefaultHandlerName Nein (empfohlen) Schnur Der Name des Handlers, der verwendet wird, wenn AutoSignIn als wahr ausgewertet wird und keine Außerkraftsetzung pro Route angegeben ist.
AutoSignIn Nein bool oder delegate Wenn "true" (Standardeinstellung) ist, versucht der Agent, ein Token für jede eingehende Aktivität abzurufen; dies kann zur Laufzeit mit Options.AutoSignIn überschrieben werden, um Aktivitätstypen zu filtern.
Handlers Ja (mindestens eine) Objekt (Wörterbuch) Zuordnung des Handlernamens zu seiner Konfiguration. Jeder Schlüssel muss eindeutig sein.

Wenn Sie einschränken möchten, auf welche Aktivitäten die automatische Anmeldung angewendet wird, legen Sie ein Prädikat wie das folgende fest: Options.AutoSignIn = (context, ct) => Task.FromResult(context.Activity.IsType(ActivityTypes.Message));.

Eigenschaften der Einstellungen

In der folgenden Tabelle wird das geschachtelte Settings Objekt beschrieben, das auf einen einzelnen OAuth-Handler angewendet wird und die Darstellung von Anmeldekarten, das Wiederholungsverhalten, Zeitüberschreitungen und die optionale OBO-Austauschkonfiguration steuert.

Eigentum Erforderlich Typ Description
AzureBotOAuthConnectionName Yes Schnur OAuth-Verbindungsname, der in der Azure Bot-Ressource definiert ist.
OBOConnectionName Nein (nur OBO) Schnur Name einer Agent-SDK-Verbindung, die verwendet wird, um einen On-Behalf-Of-Token-Austausch durchzuführen.
OBOScopes Nein (nur OBO) string[] Während des OBO-Austauschs angeforderte Berechtigungen; wenn nicht angegeben, können Sie OBOConnectionName manuell ExchangeTurnTokenAsync aufrufen.
Title Nein Schnur Benutzerdefinierter Anmeldekartentitel; Standardmäßig wird " Anmelden" verwendet.
Text Nein Schnur Schaltflächentext der Anmeldekarte; ist standardmäßig auf "Anmelden" festgelegt.
InvalidSignInRetryMax Nein INT Maximale Anzahl von Wiederholungen zulässig, wenn der Benutzer einen ungültigen Code eingibt; Standardwert ist 2.
InvalidSignInRetryMessage Nein Schnur Meldung nach einem ungültigen Codeeintrag angezeigt; Standardmäßig ist der Anmeldecode ungültig. Geben Sie den 6-stelligen Code ein.
Timeout Nein int (ms) Die Anzahl der Millisekunden, bevor ein laufender Anmeldeversuch abläuft. Der Standardwert ist 900000 (15 Minuten).

Welcher Typ soll verwendet werden?

Verwenden Sie die folgende Tabelle, um zu entscheiden, welcher Ansatz zu Ihrem Szenario passt.

Auswahl Verwenden Sie, wenn
Automatische Anmeldung Sie möchten, dass jede eingehende Aktivität automatisch ein Token erhält, oder Sie möchten eine gefilterte Teilmenge (z. B. nur Nachrichten oder alles außer Ereignissen), indem Sie ein Prädikat UserAuthorizationOptions.AutoSignInangeben.
Pro Route Nur bestimmte Routenhandler benötigen Token oder unterschiedliche Routen müssen unterschiedliche OAuth-Verbindungen (und daher unterschiedliche Token) verwenden. Dies ergänzt die globale automatische Anmeldung. Wenn beide aktiviert sind, hat der Durchlauf Zugriff auf Token von beiden.

Verwenden des Tokens im Code (nicht-OBO)

In diesem Abschnitt wird gezeigt, wie Sie das Benutzertoken abrufen und verwenden, das direkt von Ihrer Azure Bot OAuth-Verbindung zurückgegeben wird, ohne einen On-Behalf-Of-Austausch durchzuführen. Entscheiden Sie zuerst, ob Sie globale automatische Anmeldung oder Handler pro Route bevorzugen. Rufen Sie dann innerhalb des Aktivitätshandlers so spät wie möglich auf UserAuthorization.GetTurnTokenAsync , damit das SDK das Token aktualisieren kann, wenn es nahezu abläuft. Die folgenden Beispiele veranschaulichen beide Muster.

Nur automatische Anmeldungskonfiguration

Verwenden Sie diese Konfiguration, wenn die globale automatische Anmeldung ein Token für jede eingehende Aktivität abrufen soll, ohne dass für jeden Routenhandler angegeben werden muss.

  "AgentApplication": {
    "UserAuthorization": {
      "DefaultHandlerName": "auto",
      "Handlers": {
        "auto": {
          "Settings": {
            "AzureBotOAuthConnectionName": "teams_sso",
          }
        }
      }
    }
  },

Ihr Agentcode würde ungefähr wie folgt aussehen:

public class MyAgent : AgentApplication
{
    public MyAgent(AgentApplicationOptions options) : base(options)
    {
        OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last);
    }

    public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
    {
        var token = await UserAuthorization.GetTurnTokenAsync(turnContext);

        // use the token 
    }
}

Konfiguration pro Route

Verwenden Sie eine Konfiguration pro Route, wenn Sie eine differenzierte Steuerung wünschen: Nur die Routen, die Sie explizit markieren, erwerben Token. Durch die Konfiguration pro Route werden unnötige Tokenabrufe reduziert, unterschiedliche Routen für unterschiedliche OAuth-Verbindungen (und daher unterschiedliche Ressourcen oder Geltungsbereiche) ermöglicht, und es können authentifizierte und nicht authentifizierte Routen innerhalb desselben Agents kombiniert werden. Im folgenden Beispiel ist die globale automatische Anmeldung deaktiviert, und ein einzelner messageOauth Handler wird nur an die Nachrichtenroute angefügt.

  "AgentApplication": {
    "UserAuthorization": {
      "AutoSignIn": false,
      "Handlers": {
        "messageOauth": {
          "Settings": {
            "AzureBotOAuthConnectionName": "teams_sso",
          }
        }
      }
    }
  },

Ihr Agentcode würde ungefähr wie folgt aussehen:

public class MyAgent : AgentApplication
{
    public MyAgent(AgentApplicationOptions options) : base(options)
    {
        OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last, autoSignInHandlers: ["messageOauth"]);
    }

    public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
    {
        var token = await UserAuthorization.GetTurnTokenAsync(turnContext, "messageOauth");

        // use the token
    }
}

Verwende GetTurnTokenAsync

Rufen Sie GetTurnTokenAsync jedes Mal auf, wenn Sie das Benutzertoken während eines Vorgangs benötigen. Sie können sie mehrmals aufrufen. Rufen Sie sie unmittelbar vor der Verwendung auf, damit die Aktualisierungslogik (falls erforderlich) transparent behandelt wird.

Verwenden des Tokens im Code (OBO)

On-Behalf-Of (OBO) basiert auf der anfänglichen Benutzeranmeldung, die ein austauschbares Token zurückgibt. Dies erfordert, dass die OAuth-Verbindungsbereiche einen bereich enthalten, der einem Bereich entspricht, der von der downstream-API verfügbar gemacht wird (z. B. wenn der verfügbar gemachte Bereich ist defaultScopes, der konfigurierte Bereich kann sein api://botid-{{clientId}}/defaultScopes). Das Agents SDK führt dann einen Austausch über die Microsoft Authentication Library (MSAL) durch, indem eine konfigurierte Verbindung verwendet wird, die durch OBOConnectionName und die Liste von OBOScopes identifiziert wird. Wenn beide OBOConnectionName und OBOScopes in der Konfiguration vorhanden sind, erfolgt der Austausch automatisch, und Sie erhalten das endgültige Token über GetTurnTokenAsync. Wenn eine der beiden Komponenten fehlt, können Sie den Austausch zur Laufzeit explizit mit ExchangeTurnTokenAsync durchführen, sodass Sie die Verbindungs- oder Gültigkeitsbereichsliste dynamisch auflösen können.

OBO in Konfiguration

Verwenden Sie dieses Muster, wenn Sie die nachgelagerte Ressource und bereiche kennen, die Sie zur Konfigurationszeit benötigen. Wenn Sie sowohl OBOConnectionName als auch OBOScopes bereitstellen, führt das SDK während des Anmeldevorgangs automatisch den On-Behalf-Of-Austausch durch. Dies bedeutet, dass nachfolgende Aufrufe von GetTurnTokenAsync das OBO-Token direkt zurückgeben, ohne dass zusätzlicher Laufzeitcode erforderlich ist.

  "AgentApplication": {
    "UserAuthorization": {
      "DefaultHandlerName": "auto",
      "Handlers": {
        "auto": {
          "Settings": {
            "AzureBotOAuthConnectionName": "teams_sso",
            "OBOConnectionName": "ServiceConnection",
            "OBOScopes": [
              "https://myservicescope.com/.default"
            ]
          }
        }
      }
    }
  },
  "Connections": {
    "ServiceConnection": {
      "Settings": {
        "AuthType": "FederatedCredentials",
        "AuthorityEndpoint": "https://login.microsoftonline.com/{{TenantId}}",
        "ClientId": "{{ClientId}}",
        "FederatedClientId": "{{ManagedIdentityClientId}}",
        "Scopes": [
          "https://api.botframework.com/.default"
        ]
      }
    }
  },

Ihr Agentcode würde ungefähr wie folgt aussehen:

public class MyAgent : AgentApplication
{
    public MyAgent(AgentApplicationOptions options) : base(options)
    {
        OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last);
    }

    public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
    {
        var token = await UserAuthorization.GetTurnTokenAsync(turnContext);

        // use the token
    }
}

OBO Exchange zur Laufzeit

Verwenden Sie einen Laufzeitaustausch, wenn die nachgeschaltete Ressource, Bereiche oder sogar die Verbindung, die Sie verwenden müssen, nicht in der Konfiguration behoben werden kann, z. B. wenn Bereiche von Mandanten, Benutzerrolle oder Funktions-Kennzeichnung abhängen. In diesem Modell konfigurieren Sie optional das OBOConnectionName und rufen dann ExchangeTurnTokenAsync mit den Bereichen auf, die Sie zur Laufzeit festlegen, und erhalten ein ausgetauschtes Token, das Sie sofort verwenden können.

  "AgentApplication": {
    "UserAuthorization": {
      "DefaultHandlerName": "auto",
      "Handlers": {
        "auto": {
          "Settings": {
            "AzureBotOAuthConnectionName": "teams_sso",
            "OBOConnectionName": "ServiceConnection"
          }
        }
      }
    }
  },
  "Connections": {
    "ServiceConnection": {
      "Settings": {
        "AuthType": "FederatedCredentials",
        "AuthorityEndpoint": "https://login.microsoftonline.com/{{TenantId}}",
        "ClientId": "{{ClientId}}",
        "FederatedClientId": "{{ManagedIdentityClientId}}",
        "Scopes": [
          "https://api.botframework.com/.default"
        ]
      }
    }
  },

Ihr Agentcode würde ungefähr wie folgt aussehen:

public class MyAgent : AgentApplication
{
    public MyAgent(AgentApplicationOptions options) : base(options)
    {
        OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last);
    }

    public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
    {
        var scopes = GetScopes();

        var exchangedToken = await UserAuthorization.ExchangeTurnTokenAsync(turnContext, exchangeScopes: scopes);

        // use the token
    }
}

Regionale OAuth-Einstellungen

Für Nicht-US-Regionen müssen Sie den vom Agent verwendeten Tokendienstendpunkt aktualisieren.

Fügen Sie Folgendes hinzu:appsettings.json

"RestChannelServiceClientFactory": {
   "TokenServiceEndpoint": "{{service-endpoint-uri}}"
}

Verwenden Sie für service-endpoint-urlden geeigneten Wert aus der folgenden Tabelle für Public-Cloud-Bots mit Data Residency in der angegebenen Region.

URI Region
https://europe.api.botframework.com Europa
https://unitedstates.api.botframework.com USA
https://india.api.botframework.com Indien