您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

直接线路 API 3.0 中的身份验证

客户端可以使用从 Bot Framework 门户中的 Direct Line 通道配置页获取的机密或使用在运行时获得的令牌来对 Direct Line API 3.0 的请求进行身份验证。 应使用以下格式在每个请求的 Authorization 标头中指定机密或令牌:

Authorization: Bearer SECRET_OR_TOKEN

机密和令牌

Direct Line 机密是可用于访问属于关联的机器人的任何会话的主密钥。 机密还可用于获取令牌。 机密不会过期。

Direct Line 令牌是可用于访问单个会话的密钥。 令牌会过期,但可以进行刷新。

必须根据安全注意事项确定何时或者是否使用 机密 密钥或 令牌。 在保持谨慎的前提下,可以有目的性地公开机密密钥。 事实上这是默认的行为,因为这样可以让 Direct Line 判断客户端是否合法。 不过,一般而言,如果你要尝试保存用户数据,则需要考虑到安全性。 有关详细信息,请参阅安全注意事项部分。

如果你要创建服务到服务应用程序,在 Direct Line API 请求的 Authorization 标头中指定机密可能是最简单的方法。 如果你要编写客户端在 Web 浏览器或移动应用中运行的应用程序,你可能想要交换你的机密以获取令牌(仅适用于单个会话,且在不刷新的情况下会过期)并在 Direct Line API 请求的 Authorization 标头中指定令牌。 选择最适合你的安全模型。

备注

你的 Direct Line 客户端凭据与你的机器人的凭据是不同的。 这让你能够独立修改你的密钥,并使你能够在不泄漏你的机器人的密码的情况下共享客户端令牌。

获取 Direct Line 机密

可以在 Azure 门户中通过 Direct Line 通道配置页为机器人获取 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 机密的值。

以下代码片段提供了 Generate Token 请求和响应的示例。

请求

POST https://directline.botframework.com/v3/directline/tokens/generate
Authorization: Bearer RCurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0

请求的有效负载(其中包含令牌参数)是可选的,但建议使用。 生成可以发送回 Direct Line 服务的令牌时,请提供以下有效负载,使连接更安全。 包括这些值以后,Direct Line 就可以对用户 ID 和名称执行其他安全验证,阻止恶意客户端篡改这些值。 包括这些值还可以改进 Direct Line 发送聊天更新活动的功能,让它在用户加入聊天以后立即生成聊天更新。 如果未提供此信息,则用户必须先发送内容,然后 Direct Line 才会发送聊天更新。

{
  "user": {
    "id": "string",
    "name": "string"
  },
  "trustedOrigins": [
    "string"
  ]
}
参数 类型 说明
user.id 字符串 可选。 用户的特定于通道的 ID,可以在令牌中编码。 对于 Direct Line 用户,此项必须以 dl_ 开头。 可以为每个聊天创建唯一的用户 ID。为了增加安全性,应该确保此 ID 不可猜测。
user.name 字符串 可选。 用户的便于显示的名称,可以在令牌中编码。
trustedOrigins 字符串数组 可选。 可以在令牌中嵌入的受信任域的列表。 这些是可以托管机器人网络聊天客户端的域。 这应该与机器人的 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。 但是,与启动会话操作不同的是,生成令牌操作不会启动会话、不会联系机器人、也不会创建流式处理 WebSocket URL。

如果计划将令牌分发给客户端并希望它们启动会话,请使用生成令牌操作。 如果打算立即启动会话,请改用启动会话操作。

刷新 Direct Line 令牌

只要 Direct Line 令牌未过期,就可以无次数限制地刷新它。 无法刷新已过期的令牌。 若要刷新 Direct Line 令牌,请发出此请求:

POST https://directline.botframework.com/v3/directline/tokens/refresh
Authorization: Bearer TOKEN_TO_BE_REFRESHED

在此请求的 Authorization 标头中,将 TOKEN_TO_BE_REFRESHED 替换为你想要刷新的 Direct Line 令牌。

以下代码片段提供了 Refresh Token 请求和响应的示例。

请求

POST https://directline.botframework.com/v3/directline/tokens/refresh
Authorization: Bearer CurR_XV9ZA.cwA.BKA.iaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xn

响应

如果请求成功,响应将包含新的 token(它对与以前令牌相同的会话有效)以及 expires_in 值(它指示新令牌过期之前的秒数)。 为使新令牌仍然可用,必须在其过期前刷新令牌

HTTP/1.1 200 OK
[other headers]
{
  "conversationId": "abc123",
  "token": "RCurR_XV9ZA.cwA.BKA.y8qbOF5xPGfiCpg4Fv0y8qqbOF5x8qbOF5xniaJrC8xpy8qbOF5xnR2vtCX7CZj0LdjAPGfiCpg4Fv0",
  "expires_in": 1800
}

Azure 机器人服务身份验证

此部分提供的信息基于通过 Azure 机器人服务向机器人添加身份验证一文。

可以通过 Azure 机器人服务身份验证 对用户进行身份验证并从各个标识提供者(例如 Azure Active DirectoryGitHubUber 等)处获取 访问令牌。 也可为自定义 OAuth2 标识提供者配置身份验证。 因此,你可以编写适用于所有受支持的标识提供者和通道的 身份验证代码。 若要利用这些功能,需执行以下步骤:

  1. 以静态方式在机器人上配置 settings,其中包含应用程序注册到标识提供者时的详细信息。
  2. 使用在上一步提供的应用程序信息所支持的 OAuthCard 登录用户。
  3. 通过 Azure 机器人服务 API 检索访问令牌。

安全注意事项

将 Azure 机器人服务身份验证与网上聊天配合使用时,必须牢记一些重要的安全注意事项。

  1. 模拟。 此处的模拟是指攻击者让机器人认为攻击者是别人。 在网上聊天中,攻击者可能会通过 更改网上聊天实例的用户 ID 来模拟其他某人。 若要防止这种情况,建议机器人开发者使用 不可猜出的用户 ID

    如果启用 增强的身份验证 选项,Azure 机器人服务可以进一步检测并拒绝任何用户 ID 更改。 这意味着,从 Direct Line 发送到机器人的消息中的用户 ID (Activity.From.Id) 将始终与初始化网上聊天时所用的用户 ID 相同。 请注意,此功能要求用户 ID 以 dl_ 开头。

    备注

    如果在交换令牌的机密时提供 User.Id,该 User.Id 会嵌入到令牌中。 直接线路确保发送到机器人的消息具有该 ID 作为活动的 From.Id。如果客户端向具有不同 From.Id 的直接行发送消息,则在将消息转发到机器人之前,会将消息更改为 令牌中的 Id 。 因此,使用用户 ID 初始化频道机密后,不能使用其他用户 ID

  2. 用户标识。 必须指出的是,需处理两种用户标识:

    1. 通道中的用户标识。
    2. 机器人感兴趣的标识提供者中的用户标识。

    当机器人要求用户 A 在通道中登录到标识提供者 P 时,登录过程必须确保用户 A 是登录到 P 的用户。如果允许其他用户 B 登录,则用户 A 可以通过机器人访问用户 B 的资源。 在网上聊天中,我们有 2 种机制来确保正确的用户登录,如下文所述。

    1. 在登录结束时,用户会收到一个随机生成的6位数代码, (神奇代码) 。 用户必须在启动登录的会话中键入该代码,以便完成登录过程。 此机制容易导致糟糕的用户体验。 另外,它容易受到钓鱼攻击。 恶意用户可能会诱骗另一用户登录,然后通过钓鱼获得幻码。

    2. 由于前一方法存在问题,Azure 机器人服务去除了对幻码的要求。 Azure 机器人服务确保登录过程只能在网上聊天本身所在的 浏览器会话 中完成。 若要启用此保护,作为机器人开发人员,必须使用 Web 聊天 令牌启动 Direct Line,该令牌包含可托管机器人的 Web 聊天 客户端 的受信任域 的列表。 在以前,你只能将未记录的可选参数传递给 Direct Line 令牌 API,以这种方式获取该令牌。 现在,由于有了增强型身份验证选项,你可以在 Direct Line 配置页中以静态方式指定受信任域(源)列表。

    另请参阅通过 Azure 机器人服务向机器人添加身份验证

代码示例

以下 .NET 控制器适用于已启用的增强型身份验证选项,返回 Direct Line 令牌和用户 ID。

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 令牌和用户 ID。

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');
        }
    });
});

其他资源