Bemærk
Adgang til denne side kræver godkendelse. Du kan prøve at logge på eller ændre mapper.
Adgang til denne side kræver godkendelse. Du kan prøve at ændre mapper.
En agent bruger OAuth til at logge brugere ind og få tokens til downstream-ressourcer (såsom Microsoft Graph) uden selv at håndtere legitimationsoplysninger. Azure Bot Service administrerer tokenudvekslingen, og agenten henter det resulterende brugertoken under en runde.
Oversigt
Brugen af OAuth i en agent involverer tre aktiviteter:
- Konfigurer OAuth på Azure Bot og app-registrering: Opret en eller flere OAuth-forbindelser på din Azure Bot-ressource, hver bakket op af en Microsoft Entra ID-appregistrering. Tilføjelse af brugerautorisation ved brug af legitimationsoplysningerne i organisationsnetværk dækker den mest almindelige tilgang. Andre legitimationstyper, såsom klienthemmeligheder eller certifikater, understøttes også. For det fulde sæt af muligheder, se Grundlæggende om Bot Service-godkendelse.
- Konfigurer matchende indstillinger i agenten: Hver OAuth-forbindelse på Azure Bot er knyttet til én OAuth-handler i agentens konfiguration. Se Indstillinger. For generel agentopsætning, se Hvad er SDK til Microsoft 365-agenter.
- Brug tokens i koden: Under en runde henter du brugertokenet – eller udfører en OBO (På vegne af)-udveksling – via agentens brugerautorisations-API. Se Brug tokenet i kode (ikke-OBO) og Brug tokenet i kode (OBO).
Hav følgende begreber i tankerne, mens du læser resten af denne artikel:
- En Azure Bot kan indeholde flere OAuth-forbindelser. For eksempel én forbindelse til Microsoft Graph og en anden til GitHub. Hver forbindelse konfigureres uafhængigt på Azure Botten.
- Der er en 1:1-relation mellem en OAuth-forbindelse på Azure Botten og en OAuth-handler i agenten. En handlers
AzureBotOAuthConnectionName-indstilling navngiver den Azure Bot-forbindelse, den bruger. For at bruge to forbindelser, definer to handlere. - Agentens brugerautorisations-API er den grænseflade, du kalder i koden. I .NET er dette
AgentApplication.UserAuthorization– for eksempelGetTurnTokenAsyncat læse et token ogExchangeTurnTokenAsyncat udføre en OBO-udveksling. De tilsvarende grænseflader findesauthorizationi JavaScript ogauthi Python.
For arbejdsprøver, se eksemplerne på automatisk logon og OBO for:
Sprogunderstøttelse for OAuth
Agents SDK understøtter OAuth til .NET, JavaScript og Python. Kernekoncepterne er de samme i alle sprog: OAuth-handlere, tilknytning af handlere til ruter og OBO-udveksling. Kun konfigurationsformatet og handlerens API-navne adskiller sig:
| Sprog | Hvor du konfigurerer | API-grænseflade |
|---|---|---|
| .NET |
appsettings.json (eller kode i Program.cs) |
AgentApplication.UserAuthorization |
| JavaScript |
.env miljøvariabler |
AgentApplication.authorization |
| Python |
.env miljøvariabler |
AgentApplication.auth |
For JavaScript og Python bruger .env-nøglerne de samme hierarkiske navne som .NET-strukturen appsettings.json , hvor hvert niveau er adskilt af en dobbelt understregning (__). JavaScript-nøgler beholder de bladnavne med camel case, der vises i tabellerne (for eksempel, azureBotOAuthConnectionName). Python-nøgler er med store bogstaver (for eksempel AZUREBOTOAUTHCONNECTIONNAME).
Vigtigt!
Global auto-login (AutoSignIn) og DefaultHandlerName understøttes kun i .NET. I JavaScript og Python tilknytter du OAuth-handlere til specifikke ruter, som vist i Rutevis konfiguration.
Indstillinger
Et brugergodkendelsesobjekt i AgentApplication styrer, hvordan agenten henter brugertokens. Som minimum navngiver hver handler den Azure Bot OAuth-forbindelse, den bruger. Følgende eksempler viser den minimale struktur i hvert sprog. De følgende tabeller beskriver resten af de tilgængelige egenskaber, og OBO-sektionerne dækker OBOConnectionName og OBOScopes indstillingerne.
I .NET konfigureres brugergodkendelse under AgentApplicationappsettings.json:
"AgentApplication": {
"UserAuthorization": {
"DefaultHandlerName": "{{handler-name}}",
"AutoSignIn": true | false,
"Handlers": {
"{{handler-name}}": {
"Settings": {
"AzureBotOAuthConnectionName": "{{azure-bot-connection-name}}"
}
}
}
}
}
I JavaScript konfigureres brugergodkendelse med miljøvariabler i filen .env:
# Connection used to authenticate the agent itself
connections__serviceConnection__settings__clientId=
connections__serviceConnection__settings__clientSecret=
connections__serviceConnection__settings__tenantId=
connectionsMap__0__connection=serviceConnection
connectionsMap__0__serviceUrl=*
# OAuth handler named "{{handler-name}}"
AgentApplication__UserAuthorization__Handlers__{{handler-name}}__Settings__azureBotOAuthConnectionName={{azure-bot-connection-name}}
I Python konfigureres brugergodkendelse med miljøvariabler i filen .env:
# Connection used to authenticate the agent itself
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=
# OAuth handler named "{{handler-name}}"
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__{{handler-name}}__SETTINGS__AZUREBOTOAUTHCONNECTIONNAME={{azure-bot-connection-name}}
Egenskaber for UserAuthorization
Følgende tabel viser de overordnede UserAuthorization-egenskaber, der bestemmer, hvordan handlere vælges, og hvordan tokens hentes for hver indkommende aktivitet.
| Egenskab | Obligatorisk | Type | Beskrivelse |
|---|---|---|---|
DefaultHandlerName |
Nej (anbefales) | string | kun i .NET. Navnet på den handler, der bruges, når AutoSignIn evalueres til sand, og der er ikke angivet nogen rutevis tilsidesættelse. |
AutoSignIn |
Nej | bool eller stedfortræder | kun i .NET. Når true (standard), forsøger agenten at hente et token for hver indkommende aktivitet. Tilsidesæt under kørsel med Options.AutoSignIn for at filtrere aktivitetstyper. |
Handlers |
Ja (mindst én) | objekt (ordbog) | Tilknytning fra handlernavn til konfigurationen. Hver nøgle skal være entydig. |
For at begrænse i .NET hvilke aktiviteter automatisk logon gælder for, skal du indstille et prædikat svarende til: Options.AutoSignIn = (context, ct) => Task.FromResult(context.Activity.IsType(ActivityTypes.Message));. JavaScript og Python understøtter ikke global automatisk logon. I stedet kan du logge på område ved at knytte specifikke handlernavne til individuelle ruter, som vist i rutevis-eksemplerne.
Indstillingsegenskaber
Den følgende tabel beskriver det indlejrede Settings-objekt, der anvendes på en individuel OAuth-handler, og styrer præsentation af logonkort, funktionsmåde for gentagne forsøg, timeouts og valgfri OBO-udvekslingskonfiguration.
| Egenskab | Obligatorisk | Type | Beskrivelse |
|---|---|---|---|
AzureBotOAuthConnectionName |
Ja | string | OAuth-forbindelsesnavn defineret på Azure Bot-ressourcen. |
OBOConnectionName |
Nej (kun OBO) | string | Navnet på en Agents SDK-forbindelse, der bruges til at udføre en On-Behalf-Of-token-udveksling. |
OBOScopes |
Nej (kun OBO) | streng[] | Områder, der anmodes om under OBO-udveksling. Hvis det ikke angives sammen med OBOConnectionName, kan du manuelt kalde ExchangeTurnTokenAsync. |
Title |
Nej | string | Titel på brugerdefineret logonkort. Standard er Log på. |
Text |
Nej | string | Knaptekst til logonkort. Standard er Log på. |
InvalidSignInRetryMax |
Nej | heltal | Maksimalt antal tilladte forsøg, når brugeren indtaster en ugyldig kode. Standard er 2. |
InvalidSignInRetryMessage |
Nej | string | Besked vist efter ugyldig kodeindtastning. Standardindstillingen er Ugyldig loginkode. Indtast den 6-cifrede kode. |
Timeout |
Nej | int (ms) | Antal millisekunder før et igangværende logonforsøg udløber. Standard er 900000 (15 minutter). |
Bemærk!
AzureBotOAuthConnectionName, OBOConnectionName, OBOScopes, Title og Text gælder for alle tre sprog (ved brug af nøglekabinet pr. sprog, beskrevet i Sprogunderstøttelse for OAuth).
InvalidSignInRetryMax, InvalidSignInRetryMessage, og Timeout er .NET-indstillinger.
Hvilken type bør du bruge?
Brug følgende tabel til at afgøre, hvilken tilgang der passer til din situation.
| Choice | Bruges når |
|---|---|
| Automatisk logon (kun .NET) | Du ønsker, at hver indkommende aktivitet automatisk får et token, eller du ønsker et filtreret udvalg (for eksempel kun beskeder eller alt undtagen begivenheder) ved at angive et prædikat til UserAuthorizationOptions.AutoSignIn. Understøttet kun i .NET. |
| Rutevis | Kun specifikke rutehandlere behøver tokens, eller forskellige ruter skal bruge forskellige OAuth-forbindelser (og derfor forskellige tokens). Denne mulighed er den eneste mulighed i JavaScript og Python. I .NET er det additivt med global automatisk logon. Hvis begge er aktiveret i .NET, har runden adgang til tokens fra begge. |
Brug tokenet i kode (ikke OBO)
Dette afsnit viser, hvordan du kan hente og bruge brugertokenet, der direkte returneres af din Azure Bot OAuth-forbindelse, uden at udføre en On-Behalf-Of-udveksling. I .NET kan du bruge global automatisk logon eller rutevise handlere. JavaScript og Python bruger kun rutevise handlere. Inde i din aktivitetshandler, hent tokenet (GetTurnTokenAsync i .NET, authorization.getToken i JavaScript, auth.get_token i Python) så sent som muligt, så SDK'en kan opdatere tokenet, hvis det er ved at udløbe. Følgende eksempler illustrerer begge tilgange.
Automatisk logon (kun .NET)
Bemærk!
Global auto-logon og DefaultHandlerName er kun tilgængelig i .NET. For JavaScript og Python, brug Rutevis konfiguration.
Brug denne konfiguration, når global automatisk login skal hente et token for hver indkommende aktivitet uden behov for at angive rutevise handlere.
"AgentApplication": {
"UserAuthorization": {
"DefaultHandlerName": "auto",
"Handlers": {
"auto": {
"Settings": {
"AzureBotOAuthConnectionName": "teams_sso",
}
}
}
}
},
Din agentkode ser nogenlunde sådan ud:
public class MyAgent : AgentApplication
{
[MessageRoute]
public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
var token = await UserAuthorization.GetTurnTokenAsync(turnContext);
// use the token
}
}
Rutevis konfiguration
Brug en rutevis konfiguration, når du ønsker detaljeret kontrol: kun de ruter, du eksplicit markerer, modtager tokens. Rutevis konfiguration har følgende fordele:
- Det reducerer unødvendig token-hentning.
- Det tillader forskellige ruter til at målrette forskellige OAuth-forbindelser (og dermed forskellige ressourcer eller områder).
- Den lader dig blande godkendte og ikke-godkendte ruter inden for samme agent.
I det følgende eksempel er en enkelt graph handler kun tilknyttet meddelelsesruten.
I .NET deaktiveres global automatisk logon, og graph-handleren tilknyttes ruten ved brug af autoSignInHandlers.
"AgentApplication": {
"UserAuthorization": {
"AutoSignIn": false,
"Handlers": {
"graph": {
"Settings": {
"AzureBotOAuthConnectionName": "teams_sso",
}
}
}
}
},
Din agentkode ser nogenlunde sådan ud:
public class MyAgent : AgentApplication
{
[MessageRoute(autoSignInHandlers: "graph")]
public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
var token = await UserAuthorization.GetTurnTokenAsync(turnContext, "graph");
// use the token
}
}
I JavaScript skal du sende en matrix af handlernavne som det sidste argument til ruteregistreringen. Det er kun den rute, der udløser logon for graph-handleren.
AgentApplication__UserAuthorization__Handlers__graph__Settings__azureBotOAuthConnectionName=teams_sso
AgentApplication__UserAuthorization__Handlers__graph__Settings__title=Graph Sign In
AgentApplication__UserAuthorization__Handlers__graph__Settings__text=Sign in with Microsoft Graph
Din agentkode ser nogenlunde sådan ud:
class MyAgent extends AgentApplication {
constructor () {
super({ storage: new MemoryStorage() })
// the `graph` handler runs only for this route
this.onMessage('-me', this._profileRequest, ['graph'])
}
private _profileRequest = async (context, state) => {
const tokenResponse = await this.authorization.getToken(context, 'graph')
// use tokenResponse.token
}
}
I Python, giv auth_handlers videre til rutedekoratøren. Det er kun den rute, der udløser logon for GRAPH-handleren.
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__GRAPH__SETTINGS__AZUREBOTOAUTHCONNECTIONNAME=teams_sso
Din agentkode ser nogenlunde sådan ud:
@AGENT_APP.message(re.compile(r"^/(me|profile)$", re.IGNORECASE), auth_handlers=["GRAPH"])
async def profile_request(context: TurnContext, state: TurnState) -> None:
token_response = await AGENT_APP.auth.get_token(context, "GRAPH")
# use token_response.token
Hent tokenet under en tur
Hent brugertokenet, når du har brug for det i en tur. Du kan kalde det flere gange. Kald det umiddelbart før brug, så opdateringslogikken (hvis nødvendigt) håndteres automatisk.
| Sprog | Ring til |
|---|---|
| .NET |
GetTurnTokenAsync(turnContext, handlerName) |
| JavaScript | authorization.getToken(context, handlerName) |
| Python | auth.get_token(context, handler_name) |
Brug tokenet i kode (OBO)
On-Behalf-Of (OBO) er afhængig af, at det første brugerlogon returnerer et token, der kan udveksles. Det kræver, at OAuth-forbindelsens omfang inkluderer et, der svarer til et omfang, der eksponeres af downstream API'en (for eksempel hvis det eksponerede omfang er defaultScopes, kan det konfigurerede omfang være api://botid-{{clientId}}/defaultScopes). Agents SDK udfører derefter en Microsoft Authentication Library (MSAL)-udveksling med en konfigureret forbindelse identificeret af OBOConnectionName og listen for OBOScopes. Når både OBOConnectionName og OBOScopes findes i konfigurationen, sker udvekslingen automatisk, og du modtager det endelige token via standardtokenkaldet (GetTurnTokenAsync / getToken / get_token). Hvis et af dem mangler, kan du udføre udvekslingen eksplicit under kørsel med (ExchangeTurnTokenAsync i .NET, authorization.exchangeToken i JavaScript, auth.exchange_token i Python), hvilket gør det muligt for dig at bestemme forbindelses- eller omfangslisten dynamisk.
OBO i konfiguration
Brug dette mønster, når du kender de downstream-ressourcer og omfang, du har brug for under konfigurationen. Når du angiver både OBOConnectionName og OBOScopes, udfører SDK'et automatisk On-Behalf-Of-udveksling under login. Dette betyder, at efterfølgende kald til standardtoken-getter returnerer OBO-tokenet direkte uden behov for ekstra kode under kørsel.
"AgentApplication": {
"UserAuthorization": {
"AutoSignIn": false,
"Handlers": {
"graph": {
"Settings": {
"AzureBotOAuthConnectionName": "teams_sso",
"OBOConnectionName": "ServiceConnection",
"OBOScopes": [
"https://graph.microsoft.com/.default"
]
}
}
}
}
},
"Connections": {
"ServiceConnection": {
"Settings": {
"AuthType": "FederatedCredentials",
"AuthorityEndpoint": "https://login.microsoftonline.com/{{TenantId}}",
"ClientId": "{{ClientId}}",
"FederatedClientId": "{{ManagedIdentityClientId}}",
"Scopes": [
"https://api.botframework.com/.default"
]
}
}
},
Din agentkode ser nogenlunde sådan ud:
public class MyAgent : AgentApplication
{
[MessageRoute(autoSignInHandlers: "graph")]
public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
// returns the OBO token because OBOConnectionName and OBOScopes are configured
var token = await UserAuthorization.GetTurnTokenAsync(turnContext, "graph");
// use the token
}
}
I JavaScript defineres en OBO-forbindelse i forbindelseskortet og refereres til den fra handleren med oboConnectionName og oboScopes.
# Agent's own connection
connections__serviceConnection__settings__clientId=
connections__serviceConnection__settings__clientSecret=
connections__serviceConnection__settings__tenantId=
# OBO connection
connections__oboConnection__settings__clientId=
connections__oboConnection__settings__clientSecret=
connections__oboConnection__settings__tenantId=
connectionsMap__0__connection=serviceConnection
connectionsMap__0__serviceUrl=*
connectionsMap__1__connection=oboConnection
connectionsMap__1__serviceUrl=obo
AgentApplication__UserAuthorization__Handlers__graph__Settings__azureBotOAuthConnectionName=teams_sso
AgentApplication__UserAuthorization__Handlers__graph__Settings__oboConnectionName=oboConnection
AgentApplication__UserAuthorization__Handlers__graph__Settings__oboScopes=https://graph.microsoft.com/.default
Din agentkode ser nogenlunde sådan ud:
class MyAgent extends AgentApplication {
constructor () {
super({ storage: new MemoryStorage() })
this.onActivity('message', this._onMessage, ['graph'])
}
private _onMessage = async (context, state) => {
// returns the OBO token because oboConnectionName and oboScopes are configured
const tokenResponse = await this.authorization.getToken(context, 'graph')
// use tokenResponse.token
}
}
I Python defineres en OBO-forbindelse under CONNECTIONS og refereres til den fra handleren med OBOCONNECTIONNAME og OBOSCOPES.
# Agent's own connection
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=
# OBO connection
CONNECTIONS__OBO__SETTINGS__CLIENTID=
CONNECTIONS__OBO__SETTINGS__CLIENTSECRET=
CONNECTIONS__OBO__SETTINGS__TENANTID=
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__GRAPH__SETTINGS__AZUREBOTOAUTHCONNECTIONNAME=teams_sso
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__GRAPH__SETTINGS__OBOCONNECTIONNAME=OBO
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__GRAPH__SETTINGS__OBOSCOPES=https://graph.microsoft.com/.default
Din agentkode ser nogenlunde sådan ud:
@AGENT_APP.message(re.compile(r".*"), auth_handlers=["GRAPH"])
async def on_message(context: TurnContext, state: TurnState) -> None:
# returns the OBO token because OBOCONNECTIONNAME and OBOSCOPES are configured
token_response = await AGENT_APP.auth.get_token(context, "GRAPH")
# use token_response.token
OBO Exchange på kørselstidspunktet
Brug en runtime-udveksling, når du ikke kan fikse downstream-ressourcen, områder eller forbindelsen i konfigurationen. Denne situation opstår for eksempel, når områder afhænger af lejer, brugerrolle eller et funktionsflag. I denne model konfigurerer du valgfrit OBO-forbindelsen og kalder derefter udvekslingsmetoden med de områder, du vælger under turen. Du modtager et udvekslet token, som du straks kan bruge.
Kald ExchangeTurnTokenAsync med de områder, du vælger under turen.
"AgentApplication": {
"UserAuthorization": {
"AutoSignIn": false,
"Handlers": {
"graph": {
"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"
]
}
}
},
Din agentkode ser nogenlunde sådan ud:
public class MyAgent : AgentApplication
{
[MessageRoute(autoSignInHandlers: "graph")]
public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
var scopes = GetScopes();
var exchangedToken = await UserAuthorization.ExchangeTurnTokenAsync(turnContext, "graph", exchangeScopes: scopes);
// use the token
}
}
Kald authorization.exchangeToken med det handler-navn og de områder, du vælger under turen.
connections__oboConnection__settings__clientId=
connections__oboConnection__settings__clientSecret=
connections__oboConnection__settings__tenantId=
connectionsMap__1__connection=oboConnection
connectionsMap__1__serviceUrl=obo
AgentApplication__UserAuthorization__Handlers__graph__Settings__azureBotOAuthConnectionName=teams_sso
AgentApplication__UserAuthorization__Handlers__graph__Settings__oboConnectionName=oboConnection
Din agentkode ser nogenlunde sådan ud:
class MyAgent extends AgentApplication {
constructor () {
super({ storage: new MemoryStorage() })
this.onActivity('message', this._onMessage, ['graph'])
}
private _onMessage = async (context, state) => {
const scopes = getScopes()
const exchangedToken = await this.authorization.exchangeToken(context, 'graph', { scopes })
// use exchangedToken.token
}
}
Kald auth.exchange_token med de områder, du vælger under turen, og handler-navnet.
CONNECTIONS__MCS__SETTINGS__CLIENTID=
CONNECTIONS__MCS__SETTINGS__CLIENTSECRET=
CONNECTIONS__MCS__SETTINGS__TENANTID=
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__MCS__SETTINGS__AZUREBOTOAUTHCONNECTIONNAME=teams_sso
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__MCS__SETTINGS__OBOCONNECTIONNAME=MCS
Din agentkode ser nogenlunde sådan ud:
@AGENT_APP.message(re.compile(r".*"), auth_handlers=["MCS"])
async def on_message(context: TurnContext, state: TurnState) -> None:
scopes = get_scopes()
token_response = await AGENT_APP.auth.exchange_token(context, scopes, "MCS")
# use token_response.token
Regionale OAuth-indstillinger
For områder uden for USA skal du opdatere det slutpunkt for tokentjenesten, som din agent bruger.
Følgende eksempel viser .NET-konfigurationen. Tilføj det til appsettings.json:
"RestChannelServiceClientFactory": {
"TokenServiceEndpoint": "{{service-endpoint-uri}}"
}
For service-endpoint-url skal du bruge den relevante værdi fra følgende tabel for offentlige cloudrobotter med dataopbevaring i det angivne område.
| URI | Land/område |
|---|---|
https://europe.api.botframework.com |
Europa |
https://unitedstates.api.botframework.com |
USA |
https://india.api.botframework.com |
Indien |