Direct Line API 3.0 中的驗證
用戶端可以使用您 從 Bot Framework 入口網站中的 Direct Line 通道組態頁面 取得的秘密 ,或使用 您在執行時間取得的權杖 ,來驗證 Direct Line API 3.0 的要求。 應使用下列格式,在每個要求的標頭中 Authorization
指定秘密或權杖:
Authorization: Bearer SECRET_OR_TOKEN
秘密和權杖
Direct Line 秘密 是主要金鑰,可用來存取屬於相關聯 Bot 的任何交談。 秘密 也可以用來取得 權杖 。 秘密不會過期。
Direct Line 權杖 是可用來存取單一交談的金鑰。 權杖到期,但可以重新整理。
決定何時或是否要使用 秘密 金鑰或 權杖 ,必須根據安全性考慮。 如果刻意且小心地完成,則公開秘密金鑰是可以接受的。 事實上,這是預設行為,因為這可讓 Direct Line 找出用戶端是否合法。 不過,一般而言,如果您嘗試保存使用者資料,安全性就很擔心。 如需詳細資訊,請參閱安全性考慮 一節 。
如果您要建立服務對服務應用程式,在 Direct Line API 要求的標頭中 Authorization
指定 秘密 可能是最簡單的方法。 如果您要撰寫用戶端在網頁瀏覽器或行動應用程式中執行的應用程式,您可以交換您的秘密做為權杖(這只適用于單一交談,除非重新整理,否則將會過期),並在 Direct Line API 要求的標頭中 Authorization
指定 權杖 。 選擇最適合您的安全性模型。
注意
您的 Direct Line 用戶端認證與 Bot 的認證不同。 這可讓您獨立修訂金鑰,並可讓您共用用戶端權杖,而不會遺失 Bot 的密碼。
取得 Direct Line 秘密
您可以在 Azure 入口網站 中 ,透過 Bot 的 Direct Line 通道設定頁面取得 Direct Line 秘密 :
產生 Direct Line 權杖
若要產生可用來存取單一交談的 Direct Line 權杖,請先從Azure 入口網站 中的 Direct Line 通道組態頁面取得 Direct Line 秘密。 然後發出此要求,以交換 Direct Line 權杖的 Direct Line 秘密:
POST https://directline.botframework.com/v3/directline/tokens/generate
Authorization: Bearer SECRET
Authorization
在此要求的標頭中,將 SECRET 取代 為 Direct Line 秘密的值。
下列程式碼片段提供產生權杖要求和回應的範例。
Request
POST https://directline.botframework.com/v3/directline/tokens/generate
Authorization: Bearer RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0
包含權杖參數的要求承載是選擇性的,但建議使用。 產生可傳回 Direct Line 服務的權杖時,請提供下列承載,讓連線更安全。 透過包含這些值,Direct Line 可以執行使用者識別碼和名稱的額外安全性驗證,並禁止惡意用戶端竄改這些值。 包括這些值也會改善 Direct Line 傳送 交談更新 活動的能力,讓它能夠在使用者立即加入交談時產生交談更新。 未提供此資訊時,使用者必須先傳送內容,Direct Line 才能傳送交談更新。
{
"user": {
"id": "string",
"name": "string"
},
"trustedOrigins": [
"string"
]
}
參數 | 類型 | 描述 |
---|---|---|
user.id |
string | 選擇性。 在權杖內編碼之使用者的通道特定識別碼。 對於 Direct Line 使用者,這必須以 dl_ 開頭。 您可以為每個交談建立唯一的使用者識別碼,並提供更好的安全性,您應該讓此識別碼無法辨別。 |
user.name |
string | 選擇性。 在權杖內編碼之使用者的顯示易記名稱。 |
trustedOrigins |
字串陣列 | 選擇性。 要內嵌在權杖中的受信任網域清單。 這些是可以裝載 Bot 網路聊天 用戶端的網域。 這應該符合 Bot 的 Direct Line 組態頁面中的清單。 |
回應
如果要求成功,回應會 token
包含對一個交談有效的 ,以及 expires_in
指出權杖到期前秒數的值。 若要讓權杖保持可用,您必須在過期前重新整理權杖。
HTTP/1.1 200 OK
[other headers]
{
"conversationId": "abc123",
"token": "RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xn",
"expires_in": 1800
}
產生權杖與開始交談
產生權杖作業 ( POST /v3/directline/tokens/generate
) 類似于 開始交談 作業 ( POST /v3/directline/conversations
),這兩個作業都會傳回 token
可用來存取單一交談的 。 不過,不同于開始對話作業,產生權杖作業不會啟動交談、未連絡 Bot,也不會建立串流 WebSocket URL。
如果您打算將權杖散發給用戶端,並想要他們起始交談,請使用產生權杖作業。 如果您想要立即啟動交談,請改用 [開始交談 ] 作業。
重新整理 Direct Line 權杖
只要直接線路權杖尚未過期,就可以不限次數重新整理。 無法重新整理過期的權杖。 若要重新整理 Direct Line 權杖,請發出此要求:
POST https://directline.botframework.com/v3/directline/tokens/refresh
Authorization: Bearer TOKEN_TO_BE_REFRESHED
在此 Authorization
要求的標頭中,以您要重新整理的 Direct Line 權杖取代 TOKEN_TO_BE_REFRESHED 。
下列程式碼片段提供重新整理權杖要求和回應的範例。
Request
POST https://directline.botframework.com/v3/directline/tokens/refresh
Authorization: Bearer CurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xn
回應
如果要求成功,回應會包含與上一個 expires_in
權杖相同的交談有效的新 token
回應,以及指出新權杖到期前秒數的值。 若要讓新權杖保持有用,您必須 在權杖 到期之前重新整理權杖。
HTTP/1.1 200 OK
[other headers]
{
"conversationId": "abc123",
"token": "RCurR_XV9ZA.cwA.BKA.y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xniaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0",
"expires_in": 1800
}
Azure AI Bot Service 驗證
本節中提供的資訊是以透過 Azure AI Bot Service 將驗證新增至 Bot 一文為基礎 。
Azure AI Bot Service 驗證 可讓您驗證使用者,並從各種身分識別提供者取得 存取權杖 ,例如 Microsoft Entra ID 、 GitHub 、 Uber 等等。 您也可以設定自訂 OAuth2 識別提供者的驗證。 這一切可讓您撰寫 一段驗證程式代碼 ,可在所有支援的識別提供者和通道上運作。 若要使用這些功能:
- 以靜態方式
settings
在 Bot 上設定,其中包含向識別提供者註冊應用程式的詳細資料。 - 使用 ,由您在上一
OAuthCard
個步驟中提供的應用程式資訊所支援,登入使用者。 - 透過 Azure AI Bot Service API 擷取存取權杖。
安全性考量
當您搭配網路聊天 使用 Azure AI Bot Service 驗證 時,必須牢記一些重要的安全性考慮。
模擬 。 模擬是攻擊者說服 Bot 是其他人時。 在網路聊天中,攻擊者可以藉由 變更其網路聊天實例的使用者識別碼 來模擬其他人。 若要防止模擬,我們建議 Bot 開發人員讓使用者 識別碼無法 辨解。
如果您啟用 增強的驗證 選項,Azure AI Bot Service 可以進一步偵測並拒絕任何使用者識別碼變更。 這表示從 Direct Line 到 Bot 的訊息上的使用者識別碼 (
Activity.From.Id
) 一律與您初始化網路聊天相同。 此功能需要使用者識別碼以 開頭dl_
。注意
當在交換權杖的秘密時提供 User.Id 時,該 User.Id 會內嵌在權杖中。 Direct Line 可確保傳送至 Bot 的 訊息具有該識別碼作為活動的 From.Id 。如果用戶端將訊息傳送至具有不同 From.Id 的 Direct Line,則會在將訊息轉送至 Bot 之前,將它變更 為權杖 中的識別碼。 因此,在通道密碼初始化為使用者識別碼之後,您無法使用其他使用者識別碼
使用者身分識別 。 每個使用者都有多個使用者身分識別:
- 通道中的使用者身分識別。
- Bot 感興趣的身分識別提供者中使用者的身分識別。
當 Bot 要求通道中的使用者 A 登入識別提供者 P 時,登入程式必須確保使用者 A 是登入 P 的使用者。如果允許其他使用者 B 登入,則使用者 A 可以透過 Bot 存取使用者 B 的資源。 在網路聊天中,我們有兩種機制可確保正確的使用者登入,如下所述。
登入結束時,使用者會看到隨機產生的 6 位數代碼(magic code)。 使用者必須在起始登入的交談中輸入此程式碼,才能完成登入程式。 此機制往往會導致使用者體驗不佳。 此外,它仍然容易受到網路釣魚攻擊。 惡意使用者可誘使其他使用者登入,並透過網路釣魚取得魔術代碼。
由於先前方法的問題,Azure AI Bot Service 已移除魔術程式碼的需求。 Azure AI Bot Service 保證登入程式只能在與網路聊天本身相同的瀏覽器會話 中 完成。 若要啟用此保護,身為 Bot 開發人員,您必須使用 Direct Line 權杖啟動網路聊天 ,其中包含 可裝載 Bot 網路聊天 用戶端 的信任網域 清單。 之前,您只能藉由將未記載的選擇性參數傳遞至 Direct Line 權杖 API 來取得此權杖。 現在,使用增強的驗證選項,您可以在 [Direct Line 組態] 頁面中以靜態方式指定受信任的網域 (origin) 清單。
如需詳細資訊,請參閱 透過 Azure AI Bot Service 將驗證新增至 Bot。
程式碼範例
下列 .NET 控制器可搭配已啟用增強的驗證選項運作,並傳回 Direct Line Token 和使用者識別碼。
public class HomeController : Controller
{
public async Task<ActionResult> Index()
{
var secret = GetSecret();
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Post,
$"https://directline.botframework.com/v3/directline/tokens/generate");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", secret);
var userId = $"dl_{Guid.NewGuid()}";
request.Content = new StringContent(
JsonConvert.SerializeObject(
new { User = new { Id = userId } }),
Encoding.UTF8,
"application/json");
var response = await client.SendAsync(request);
string token = String.Empty;
if (response.IsSuccessStatusCode)
{
var body = await response.Content.ReadAsStringAsync();
token = JsonConvert.DeserializeObject<DirectLineToken>(body).token;
}
var config = new ChatConfig()
{
Token = token,
UserId = userId
};
return View(config);
}
}
public class DirectLineToken
{
public string conversationId { get; set; }
public string token { get; set; }
public int expires_in { get; set; }
}
public class ChatConfig
{
public string Token { get; set; }
public string UserId { get; set; }
}
下列 JavaScript 控制器可搭配已啟用增強的驗證選項運作,並傳回 Direct Line Token 和使用者識別碼。
var router = express.Router(); // get an instance of the express Router
// Get a directline configuration (accessed at GET /api/config)
const userId = "dl_" + createUniqueId();
router.get('/config', function(req, res) {
const options = {
method: 'POST',
uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
headers: {
'Authorization': 'Bearer ' + secret
},
json: {
User: { Id: userId }
}
};
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
res.json({
token: body.token,
userId: userId
});
}
else {
res.status(500).send('Call to retrieve token from Direct Line failed');
}
});
});