Merk
Tilgang til denne siden krever autorisasjon. Du kan prøve å logge på eller endre kataloger.
Tilgang til denne siden krever autorisasjon. Du kan prøve å endre kataloger.
En agent bruker OAuth til å logge på brukere og hente tokener for nedstrømsressurser (som Microsoft Graph) uten å håndtere legitimasjonen selv. Azure Bot Service håndterer tokenutvekslingen, og agenten henter det resulterende brukertokenet i løpet av en runde.
Oversikt
Bruk av OAuth i en agent innebærer tre aktiviteter:
- Konfigurer OAuth på Azure Bot og appregistrering: Lag en eller flere OAuth-tilkoblinger på Azure Bot-ressursen, hver støttet av en Microsoft Entra ID-appregistrering. Legg til brukerautorisasjon med føderert identitetslegitimasjon dekker den vanligste tilnærmingen. Andre typer legitimasjon, som klienthemmeligheter eller sertifikater, støttes også. For hele settet av alternativer kan du se Grunnleggende autentisering for robottjenester.
- Konfigurer samsvarer innstillinger i agenten: Hver OAuth-tilkobling på Azure Bot kartlegges til én OAuth-handler i agentens konfigurasjon. Se Innstillinger. For generelt agentoppsett kan du se Hva er SDK for Microsoft 365-agenter.
- Bruk tokenene i koden: Under en runde henter du brukertokenet – eller utfør en på vegne av-utveksling (OBO) – via agentens brukerautorisasjons-API. Se Bruk token i kode (ikke-OBO) og Bruk token i kode (OBO).
Husk følgende konsepter mens du leser resten av denne artikkelen:
- En Azure Bot kan inneholde flere OAuth-tilkoblinger. Eksempel: En tilkobling for Microsoft Graph og en annen for GitHub. Hver tilkobling konfigureres uavhengig på Azure Bot.
- Det er et 1:1-forhold mellom en OAuth-tilkobling på Azure Bot og et OAuth-behandlingsprogram i agenten. Et behandlingsprograms
AzureBotOAuthConnectionName-innstilling navngir Azure Bot-tilkoblingen den bruker. For å bruke to tilkoblinger må du definere to behandlingsprogrammer. - Agentens brukerautorisasjons-API er overflaten du kaller i koden. I .NET er dette
AgentApplication.UserAuthorization– for eksempelGetTurnTokenAsyncfor å lese en token ogExchangeTurnTokenAsyncutføre en OBO-utveksling. De tilsvarende flatene finnesauthorizationi JavaScript ogauthi Python.
For arbeidsprøver kan du se autopåloggingen og OBO-prøver for:
Språkstøtte for OAuth
SDK for agenter støtter OAuth for .NET, JavaScript og Python. Kjernekonseptene er de samme på alle språk: OAuth-behandlingsprogrammer, å knytte behandlingsprogrammer til ruter og OBO-utveksling. Bare konfigurasjonsformatet og behandlingsprogrammets API-navn er forskjellig:
| Språk | Hvor du konfigurerer | API-overflate |
|---|---|---|
| .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 bruker .env-nøklene de samme hierarkiske navnene som .NET appsettings.json-strukturen, med hvert nivå adskilt av en dobbel understrek (__). JavaScript-nøkler beholder bladnavnene med camel case som vises i tabellene (f.eks. azureBotOAuthConnectionName). Python-nøkler er store bokstaver (f.eks. AZUREBOTOAUTHCONNECTIONNAME).
Viktig!
Global automatisk pålogging (AutoSignIn) og DefaultHandlerName støttes bare i .NET. I JavaScript og Python knytter du OAuth-håndterere til spesifikke ruter, som vist i Per-route-konfigurasjon.
Innstillinger
Et brukergodkjenningsobjekt inne i AgentApplication styrer hvordan agenten henter brukertokener. Minst navngir hvert behandlingsprogram Azure Bot OAuth-tilkoblingen det bruker. Følgende eksempler viser den minimale strukturen i hvert språk.
Tabellene som følger beskriver resten av tilgjengelige egenskaper, og OBO-delene dekker OBOConnectionName og OBOScopes-innstillinger.
I .NET konfigurerer du brukerautorisasjon under AgentApplication i appsettings.json:
"AgentApplication": {
"UserAuthorization": {
"DefaultHandlerName": "{{handler-name}}",
"AutoSignIn": true | false,
"Handlers": {
"{{handler-name}}": {
"Settings": {
"AzureBotOAuthConnectionName": "{{azure-bot-connection-name}}"
}
}
}
}
}
I JavaScript konfigurerer du brukerautorisasjon med miljøvariabler i .envfilen:
# 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 konfigurerer du brukerautorisasjon med miljøvariabler i .envfilen:
# 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}}
UserAuthorization-egenskaper
Følgende tabell viser UserAuthorization-egenskapene på toppnivå som bestemmer hvordan håndterere velges og hvordan token skaffes for hver innkommende aktivitet.
| Egenskap | Kreves | Type | Description |
|---|---|---|---|
DefaultHandlerName |
Nei (anbefales) | string | Bare .NET. Navnet på behandlingsprogrammet som benyttes når AutoSignIn er sann og ingen overstyring per rute er angitt. |
AutoSignIn |
Nei | boolsk eller representant | Bare .NET. Når denne er satt til sann (standard), forsøker agenten å skaffe en token for hver innkommende aktivitet. Overstyr under kjøring med Options.AutoSignIn for å filtrere aktivitetstyper. |
Handlers |
Ja (minst én) | objekt (ordliste) | Tildeling av behandlingsprogramnavn til konfigurasjonen. Hver nøkkel må være unik. |
For å begrense hvilke aktiviteter automatisk pålogging gjelder for i .NET, setter du et predikat som ligner på: Options.AutoSignIn = (context, ct) => Task.FromResult(context.Activity.IsType(ActivityTypes.Message));. JavaScript og Python støtter ikke global automatisk pålogging. I stedet kan du bruke omfangspålogging ved å knytte spesifikke behandlingsprogramnavn til individuelle ruter, som vist i eksemplene per rute.
Egenskap for innstillinger
Tabellen nedenfor beskriver det nestede Settings-objektet som brukes på en individuell OAuth-håndterer og styrer presentasjon av påloggingskort, gjentaksvirkemåte, tidsavbrudd og valgfri konfigurasjon for OBO-utveksling.
| Egenskap | Kreves | Type | Beskrivelse |
|---|---|---|---|
AzureBotOAuthConnectionName |
Ja | string | OAuth-tilkoblingsnavn definert på Azure-robotressursen. |
OBOConnectionName |
Nei (bare OBO) | string | Navn på en tilkobling for SDK for agenter som brukes til å utføre en On-Behalf-Of-token-utveksling. |
OBOScopes |
Nei (bare OBO) | streng[] | Omfang forespurt under OBO-utveksling. Hvis dette utelates med OBOConnectionName, kan du kalle ExchangeTurnTokenAsync manuelt. |
Title |
Nei | string | Tittel på tilpasset påloggingskort Standardinnstillingen er Logg på. |
Text |
Nei | string | Tekst på påloggingsknappen. Standardinnstillingen er Logg på. |
InvalidSignInRetryMax |
Nei | heltall | Maksimalt antall forsøk tillatt når brukeren skriver inn en ugyldig kode. Standard er 2. |
InvalidSignInRetryMessage |
Nei | string | Melding vises etter en ugyldig kodeinntasting. Standardinnstillingen er Ugyldig påloggingskode. Skriv inn den 6-sifrede koden. |
Timeout |
Nei | int (ms) | Antall millisekunder før et pågående påloggingsforsøk utløper. Standardinnstillingen er 900 000 (15 minutter). |
Notat
AzureBotOAuthConnectionName, OBOConnectionName, OBOScopes, Title og Text gjelder for alle tre språkene (ved bruk av nøkkelkapsling per språk beskrevet i Språkstøtte for OAuth).
InvalidSignInRetryMax, InvalidSignInRetryMessage og Timeout er .NET-innstillinger.
Hvilken type bør du bruke?
Bruk tabellen nedenfor for å avgjøre hvilken tilnærming som passer din situasjon.
| Valg | Når skal det brukes |
|---|---|
| Bare pålogging (bare .NET) | Du vil at hver innkommende aktivitet automatisk skal hente et token, eller du vil ha et filtrert delsett (f.eks. bare meldinger eller alt unntatt hendelser) ved å oppgi et predikat til UserAuthorizationOptions.AutoSignIn. Støttes bare i .NET. |
| Per rute | Bare bestemte rutehåndterere trenger tokener, eller ulike ruter må bruke forskjellige OAuth-tilkoblinger (og dermed forskjellige tokens). Dette alternativet er det eneste alternativet i JavaScript og Python. I .NET er det additivt med global automatisk pålogging. Hvis begge er aktivert i .NET, har vendingen tilgang til tokener fra hver av dem. |
Bruk tokenet i kode (ikke-OBO)
Denne delen viser hvordan du kan hente og bruke brukertokenet som returneres direkte fra din Azure Bot OAuth-tilkobling uten å utføre en On-Behalf-Of-utveksling. I .NET kan du bruke global automatisk pålogging eller per-rute-behandlingsprogram. JavaScript og Python bruker bare håndterere per rute. Inne i aktivitetsbehandlingsprogrammet henter du tokenet (GetTurnTokenAsync i .NET, authorization.getToken i JavaScript, auth.get_token i Python) så sent som mulig slik at SDK-en kan oppdatere tokenet hvis den nærmer seg utløp. Følgende eksempler viser begge tilnærmingene.
Bare pålogging (bare .NET)
Notat
Global automatisk pålogging og DefaultHandlerName er bare tilgjengelige i .NET. For JavaScript og Python kan du bruke Per-rute-konfigurasjon.
Bruk denne konfigurasjonen når global automatisk pålogging skal skaffe tokenet for hver innkommende aktivitet uten behov for å spesifisere rutehåndterere.
"AgentApplication": {
"UserAuthorization": {
"DefaultHandlerName": "auto",
"Handlers": {
"auto": {
"Settings": {
"AzureBotOAuthConnectionName": "teams_sso",
}
}
}
}
},
Agentkoden din ser omtrent slik ut:
public class MyAgent : AgentApplication
{
[MessageRoute]
public async Task OnMessageAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
var token = await UserAuthorization.GetTurnTokenAsync(turnContext);
// use the token
}
}
Per-rute-konfigurasjon
Bruk en per-rute-konfigurasjon når du ønsker finkornet kontroll: bare rutene du eksplisitt angir får tokener. Per-rute-konfigurasjon har følgende fordeler:
- Det reduserer unødvendig tokenhenting.
- Det tillater ulike ruter å målrette distinkte OAuth-tilkoblinger (og dermed ulike ressurser eller omfang).
- Den lar deg blande autentiserte og uautentiserte ruter innenfor samme agent.
I det følgende eksempelet er bare ett graph-behandlingsprogram knyttet til meldingsruten.
I .NET deaktiveres global automatisk pålogging og graph-behandlingsprogrammet knyttes til ruten ved å bruke autoSignInHandlers.
"AgentApplication": {
"UserAuthorization": {
"AutoSignIn": false,
"Handlers": {
"graph": {
"Settings": {
"AzureBotOAuthConnectionName": "teams_sso",
}
}
}
}
},
Agentkoden din ser omtrent slik ut:
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 sender en matrise av behandlingsprogramnavn som siste argument til ruteregistreringen. Bare den ruten utløser pålogging for graph-behandlingsprogram.
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
Agentkoden din ser omtrent slik ut:
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 sender du auth_handlers videre til rutedekoratøren. Bare den ruten utløser pålogging for GRAPH-behandlingsprogram.
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__GRAPH__SETTINGS__AZUREBOTOAUTHCONNECTIONNAME=teams_sso
Agentkoden din ser omtrent slik ut:
@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 runde
Hent brukertokenet når du trenger det i løpet av en runde. Du kan kalle det opp flere ganger. Kall det umiddelbart før bruk, slik at oppdateringslogikken (om nødvendig) håndteres automatisk.
| Språk | Ring |
|---|---|
| .NET |
GetTurnTokenAsync(turnContext, handlerName) |
| JavaScript | authorization.getToken(context, handlerName) |
| Python | auth.get_token(context, handler_name) |
Bruk tokenet i kode (OBO)
On-Behalf-Of (OBO) er avhengig av at den første brukerpåloggingen returnerer et token som kan utveksles. Dette krever at OAuth-tilkoblingens omfang inkluderer ett som samsvarer med et omfang eksponert av det nedstrøms API-et (f.eks. hvis det eksponerte omfanget er defaultScopes, kan det konfigurerte omfanget være api://botid-{{clientId}}/defaultScopes). SDK for agenter utfører deretter en Microsoft Authentication Library (MSAL)-utveksling med en konfigurert tilkobling identifisert av OBOConnectionName og listen over OBOScopes. Når både OBOConnectionName og OBOScopes er til stede i konfigurasjonen, skjer utvekslingen automatisk, og du får det endelige tokenet gjennom standard tokenkall (GetTurnTokenAsync / getToken / get_token). Hvis noen av dem mangler, kan du utføre utvekslingen eksplisitt under kjøring med (ExchangeTurnTokenAsync i .NET, authorization.exchangeToken i JavaScript, i auth.exchange_token i Python) slik at du kan velge tilkobling eller listen over omfang dynamisk.
OBO i konfigurasjon
Bruk dette mønsteret når du vet hvilken nedstrøms ressurs og omfang du trenger ved konfigurasjon. Når du angir både OBOConnectionName og OBOScopes, utfører SDK-en automatisk On-Behalf-Of-utvekslingen under pålogging. Dette betyr at påfølgende kall til standard tokenhenter returnerer OBO-tokenet direkte uten behov for ekstra kode som må kjøres under kjøring.
"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"
]
}
}
},
Agentkoden din ser omtrent slik ut:
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 definerer du en OBO-forbindelse i tilkoblingskartet og henviser til den fra behandlingsprogram 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
Agentkoden din ser omtrent slik ut:
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 definerer du en OBO-tilkobling under CONNECTIONS og henviser den fra behandlingsprogrammet 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
Agentkoden din ser omtrent slik ut:
@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 ved kjøretid
Bruk en kjøretidsutveksling når du ikke kan fikse nedstrøms ressurser, omfang eller tilkobling i konfigurasjonen. Denne situasjonen oppstår for eksempel når omfang avhenger av leietaker, brukerrolle eller et funksjonsflagg. I denne modellen konfigurerer du valgfritt OBO-tilkoblingen og kaller deretter opp utvekslingsmetoden med omfangene du bestemmer ved rundetidspunktet. Du mottar et utvekslet token som du umiddelbart kan bruke.
Kall opp ExchangeTurnTokenAsync med omfangene du bestemmer ved rundetidspunktet.
"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"
]
}
}
},
Agentkoden din ser omtrent slik ut:
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
}
}
Kall opp authorization.exchangeToken med behandlingsprogramnavnet og omfangene du bestemmer ved rundetidspunktet.
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
Agentkoden din ser omtrent slik ut:
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
}
}
Kall opp auth.exchange_token med omfangene du bestemmer ved rundetidspunktet, og behandlingsprogrammet.
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
Agentkoden din ser omtrent slik ut:
@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-innstillinger
For områder utenfor USA oppdaterer du tokentjenesteendepunktet som agenten bruker.
Eksempelet nedenfor viser .NET-konfigurasjonen: Legg det til i appsettings.json:
"RestChannelServiceClientFactory": {
"TokenServiceEndpoint": "{{service-endpoint-uri}}"
}
For service-endpoint-url bruker du den riktige verdien fra tabellen nedenfor for roboter i offentlige skyer med datalagring i det angitte området.
| URI | Område |
|---|---|
https://europe.api.botframework.com |
Europa |
https://unitedstates.api.botframework.com |
USA |
https://india.api.botframework.com |
India |