.NET 代理程式的 OAuth 會先在您的 Azure Bot 資源和對應的應用程式註冊上佈建。 Agent 執行階段接著透過 AgentApplication 自動登入功能,為您取得並重新整理使用者權杖。 自動登入可以全域執行 (所有活動類型) 或選擇性地執行,以便只有特定路由或活動類型要求權杖。
您可以在配置中註冊多個 OAuth 處理常式,並將它們指派給特定路由,或宣告隨處使用的單一預設處理常式。 每個處理常式的 Azure 端皆已設定時,這些處理常式都可以選擇性執行代表 (OBO) 交換。 如需快速入門,請參閱 AutoSignIn 範例,或將此處顯示的設定改良為現有的代理程式。
下列各節說明如何設定 UserAuthorization、決定採用全域方法還是個別路由方法,以及在回合中擷取權杖 (標準和 OBO)。 也為非美國部署提供了區域指導。
.NET 代理程式可以在 appsettings 中設定,或透過 Program.cs 中的程式碼設定。 本文件詳細說明如何使用 appsettings。
設定
AgentApplication 內的 UserAuthorization 物件控制如何取得使用者權杖。 下列 JSON 顯示階層式結構,接著是描述UserAuthorization以及巢狀Settings物件之每個屬性的資料表。
"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}}
}
}
}
}
}
UserAuthorization 屬性
下表列出頂層 UserAuthorization 屬性,這些屬性決定如何選擇處理常式,以及如何為每個傳入活動取得 Token。
| 房產 | 為必填項目 | 類型 | Description |
|---|---|---|---|
DefaultHandlerName |
否(建議) | 字串 |
AutoSignIn 評估為 true 且未指定任何個別路由覆寫時所使用的處理常式名稱。 |
AutoSignIn |
否 | 布林值或委託 | 當為 true(預設值)時,代理程式會嘗試取得每個傳入活動的記號;可在執行階段使用 Options.AutoSignIn 來覆寫,以便篩選活動類型。 |
Handlers |
是 (至少一個) | 對象(字典) | 將處理常式名稱對應至其組態設定。 每個金鑰都必須是唯一的。 |
若要限制自動登入套用至哪些活動,請設定類似於: 的述詞。 Options.AutoSignIn = (context, ct) => Task.FromResult(context.Activity.IsType(ActivityTypes.Message));
設定屬性
下表說明套用至個別 OAuth 處理常式的巢狀 Settings 物件、控制登入卡呈現方式、重試行為、逾時,以及選用 OBO 交換設定。
| 房產 | 為必填項目 | 類型 | Description |
|---|---|---|---|
AzureBotOAuthConnectionName |
Yes | 字串 | Azure Bot 資源上定義的 OAuth 連線名稱。 |
OBOConnectionName |
否(僅限 OBO) | 字串 | 用於執行代表權杖交換的 Agent SDK 連接名稱。 |
OBOScopes |
否(僅限 OBO) | 字串[] | OBO 交換過程中要求的範圍;如果省略 OBOConnectionName,您可以手動呼叫 ExchangeTurnTokenAsync。 |
Title |
否 | 字串 | 自定義簽到卡標題;預設為登入。 |
Text |
否 | 字串 | 簽到卡按鈕文字;預設為 請登入。 |
InvalidSignInRetryMax |
否 | 整數 (int) | 使用者輸入無效代碼時允許的重試次數上限;預設值為 2。 |
InvalidSignInRetryMessage |
否 | 字串 | 輸入無效代碼後顯示的訊息;預設為無 效的登入程式碼。請輸入 6 位數的代碼。 |
Timeout |
否 | 整數 (毫秒) | 進行中的登入嘗試到期之前的毫秒數。 預設值為 900000 (15 分鐘)。 |
要使用什麼類型?
使用下表來決定哪種方法適合您的案例。
| 選擇 | 在以下情況下使用 |
|---|---|
| 自動登入 | 您是希望每個接收活動自動取得權杖,還是希望透過向 UserAuthorizationOptions.AutoSignIn 提供述詞來取得篩選出的子集 (例如只有訊息或除事件以外的所有項目)。 |
| 個別路由 | 只有特定的路由處理常式需要權杖,而不同路由則必須使用不同的 OAuth 連線(因此也必須使用不同的權杖)。 這與全域自動登入功能相輔相成。 如果兩者都已啟用,則該回合可以存取兩者中每一個的權杖。 |
在程式代碼中使用權杖 (非 OBO)
本節示範如何擷取和使用 Azure Bot OAuth 連線直接回傳的使用者權杖,而不執行代表交換。 先決定您想要的是全域自動登入還是個別路由處理常式;然後,在活動處理常式中,盡可能延遲呼叫 UserAuthorization.GetTurnTokenAsync,讓 SDK 可以在權杖即將到期時重新整理權杖。 下列範例說明這兩種模式。
僅自動登入設定
當全域自動登入必須為每個接收活動取得權杖,而不需要指定個別路由處理常式時,使用此設定。
"AgentApplication": {
"UserAuthorization": {
"DefaultHandlerName": "auto",
"Handlers": {
"auto": {
"Settings": {
"AzureBotOAuthConnectionName": "teams_sso",
}
}
}
}
},
Agent 程式碼看起來會像這樣:
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
}
}
只有個別路由的設定
要進行精細控制時,使用個別路由設定:只有您明確標示的路由會取得存取權杖。 個別路由設定可減少不必要的權杖擷取、允許不同的路由選擇不同的 OAuth 連線做為目標 (因此是不同的資源或範圍),並可讓您在相同的 Agent 中混用已驗證和未驗證的路由。 在下列範例中,會停用全域自動登入,而且單一 messageOauth 處理常式只會附加至訊息路由。
"AgentApplication": {
"UserAuthorization": {
"AutoSignIn": false,
"Handlers": {
"messageOauth": {
"Settings": {
"AzureBotOAuthConnectionName": "teams_sso",
}
}
}
}
},
Agent 程式碼看起來會像這樣:
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
}
}
使用 GetTurnTokenAsync
在回合期間,每當你需要使用者權杖時,就呼叫 GetTurnTokenAsync 。 您可以多次叫用它。 在使用前立即進行呼叫,以便透明處理重新整理邏輯 (如有必要)。
在程式代碼中使用權杖 (OBO)
On-Behalf-Of (OBO) 依賴於初始使用者登入,傳回可交換的權杖。 這需要 OAuth 連線的範圍包含對應至下游 API 公開之範圍的範圍 (例如,如果公開的範圍是 defaultScopes,則設定的範圍可能是 api://botid-{{clientId}}/defaultScopes)。 然後,代理程式 SDK 會使用由 OBOConnectionName 識別的已設定連線和 OBOScopes 的清單來執行 Microsoft 驗證程式庫(MSAL)的交換。 當組態中同時 OBOConnectionName 存在 和 OBOScopes 時,交換會自動發生,您可以透過 GetTurnTokenAsync取得最終權杖。 如果缺少其中一個,您可以在執行階段使用ExchangeTurnTokenAsync明確地進行交換,以便動態解析連線或作用域清單。
設定中的 OBO
當您知道組態時所需的下游資源和範圍時,請使用此模式。 同時提供 OBOConnectionName 和 OBOScopes 時,SDK 會在登入過程中自動執行代表交換。 這表示後續呼叫 GetTurnTokenAsync 會直接傳回 OBO 權杖,而不需要額外的執行階段程式碼。
"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"
]
}
}
},
Agent 程式碼看起來會像這樣:
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 交換
無法在設定中修正下游資源、範圍,甚至無法在其中修正您必須使用的連線時 (例如,範圍取決於租用戶、使用者角色或功能旗標時),請使用執行階段交換。 在此模型中,您可以 (選擇性) 設定 OBOConnectionName,然後使用您在回合期間決定的範圍來呼叫 ExchangeTurnTokenAsync,並接收可立即套用的交換權杖。
"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"
]
}
}
},
Agent 程式碼看起來會像這樣:
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
}
}
區域 OAuth 設定
對於非美國地區,您需要更新您的代理所使用的權杖服務端點。
將以下內容新增至 appsettings.json:
"RestChannelServiceClientFactory": {
"TokenServiceEndpoint": "{{service-endpoint-uri}}"
}
對於 service-endpoint-url,針對在指定區域中具有資料存放位置的公有雲機器人,使用下表中的適當值。
| URI | 區域 |
|---|---|
https://europe.api.botframework.com |
歐洲 |
https://unitedstates.api.botframework.com |
美國 |
https://india.api.botframework.com |
印度 |