你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

向机器人添加身份验证

适用于: SDK v4

v4 SDK Azure 机器人服务有助于开发可以访问需要用户身份验证的联机资源的机器人。 机器人不需要管理身份验证令牌,因为 Azure 会使用 OAuth 2.0 来根据每个用户的凭据生成令牌。 机器人使用 Azure 生成的令牌来访问这些资源。 这样,用户就不必向机器人提供 ID 和密码来访问安全的资源,而只能向受信任的标识提供者提供。

有关用户如何Bot Framework此类身份验证的概述,请参阅 用户身份验证

本文引用了两个示例。 一个示例演示如何获取身份验证令牌。 另一个更复杂,演示如何代表Graph访问 Microsoft 应用。 在这两种情况下,可以使用 Azure Active Directory (Azure AD) v1 或 v2 作为标识提供者来获取机器人的 OAuth 令牌。 本文介绍了如何:

完成本文后,就会获得一个能够响应一些简单任务的机器人。 在 Microsoft Graph示例中,可以发送电子邮件、显示你是谁,以及检查最近的电子邮件。 无需发布机器人即可测试 OAuth 功能;但是,机器人需要有效的 Azure 应用 ID 和密码。

网络聊天和 Direct Line 注意事项

重要

在使用安全Direct Line连接到机器人时,需使用启用了增强身份验证Web 聊天安全风险。 有关详细信息,请参阅 Direct Line 增强身份验证

先决条件

示例 BotBuilder 版本 演示
C#、JavaScript、Java Python中的身份验证 v4 OAuthCard 支持
C#、JavaScript、JavaPython中的 身份验证MSGraph v4 Microsoft Graph OAuth 2.0 的 API 支持

有关示例

若要运行本文中引用的示例,需要以下各项:

  1. 一Azure Active Directory (Azure AD) 应用程序,在 Azure 中注册机器人资源。 此应用程序允许机器人访问受保护的外部资源,如 Microsoft Graph。 它还允许用户通过多个频道(如 Web Chat)与机器人通信。
  2. 一个单独的充当标识提供者的 Azure AD 应用程序。 此应用程序提供在机器人与受保护资源之间建立 OAuth 连接所需的凭据。 请注意,本文使用 Active Directory 作为标识提供者。 另外还支持许多其他的提供者。

重要

每当你在 Azure 中注册机器人时,系统都会为它分配一个 Azure AD 应用程序。 但是,此应用程序可确保从通道到机器人的访问的安全性。 对于每个受保护的外部资源,如果希望机器人代表用户对其进行访问,则需要一个额外的 Azure AD 应用程序。

创建资源

创建 Azure 机器人 资源,使你能够向 Azure bot 服务注册你的机器人。

警告

Web 应用机器人机器人通道注册 已弃用,但现有资源将继续工作。 应改为使用 Azure 机器人

  1. 转到 Azure 门户

  2. 在右侧窗格中,选择 " 创建资源"。

  3. 在搜索框中,输入 机器人,然后按 enter

  4. 选择 Azure 机器人 卡。

    选择 Azure 机器人资源

  5. 选择“创建”。

  6. 在必填字段中输入值。 选择要创建的应用类型,以及是否使用现有的或创建新的标识信息。

    使用新的应用 ID 创建用户分配的托管标识 Azure 机器人资源。

  7. 选择“查看 + 创建”。

  8. 如果验证通过,请选择 " 创建"。

  9. 选择“转到资源组”。 应该会看到所选资源组中列出的机器人和相关资源。

  10. 选择 "从 GitHub 获取 SDK" ,以通过 bot Framework SDK 生成机器人。

    在 SDK 中创建机器人

提示

当 Azure 使用新的应用 ID 创建新的单租户或多租户 Azure 机器人资源时,它还会生成 密码 并将密码存储在 Azure Key Vault 中。

Key Vault 是一种提供集中式机密管理的服务,可以完全控制访问策略和审核历史记录。 有关详细信息,请参阅使用应用服务和 Azure Functions 的 Key Vault 引用。 使用该服务需要付费。 有关详细信息,请参阅 Key Vault 定价

机器人标识信息

需要将标识信息添加到机器人的配置文件。 该文件因创建机器人所使用的编程语言而异。

重要

机器人 Framework SDK 的 Java 和 Python 版本仅支持多租户机器人。 C # 和 JavaScript 版本支持所有这三种应用程序类型,用于管理机器人的标识。

语言 文件名 备注
C# appsettings.json 支持所有三种应用程序类型来管理机器人的标识。
JavaScript .env 支持所有三种应用程序类型来管理机器人的标识。
Java 应用程序. 属性 仅支持多租户机器人。
Python config.py 仅支持多租户机器人。 提供标识属性作为方法调用的参数 os.environ.get

需要添加的标识信息取决于机器人的应用程序类型。 在配置文件中提供以下值。

仅适用于 c # 和 JavaScript bot。

属性
MicrosoftAppType UserAssignedMSI
MicrosoftAppId 用户分配的托管标识的客户端 ID。
MicrosoftAppPassword 对于用户分配的托管标识机器人,请将此项留空。
MicrosoftAppTenantId 机器人的应用租户 ID。

向机器人的 web 应用添加 用户分配的托管标识

  1. 请参阅机器人的 web 应用的应用服务页。
  2. 在导航窗格中的 "设置" 下,选择 "标识"。
  3. 在 " 标识 " 窗格中,选择 " 用户分配 " 选项卡,并 添加 (+) 。
  4. 在 " 添加用户分配的托管标识 " 窗格上:
    1. 选择订阅。

    2. 对于 用户分配的托管标识,请选择机器人的托管标识。 如果为你自动生成了托管标识,则它将具有与机器人相同的名称。

    3. 选择 " 添加 " 以将此标识用于你的机器人。

      应用服务标识页,其中包含所选机器人的托管标识。

获取机器人应用或租户 ID:

  1. 请参阅机器人的 Azure 机器人资源页。
  2. 中转到机器人的 配置 窗格。 在此处,你可以复制机器人的 Microsoft 应用 id应用租户 id

提示

当 Azure 创建单租户或多租户机器人时,它会将应用密码存储在 Azure Key Vault 中。

若要从 Azure Key Vault 获取 机器人的应用密码 ,请参阅:

Azure AD 标识服务

应用程序Azure Active Directory (Azure AD) 云标识服务,可用于生成使用行业标准协议(如 OAuth 2.0)安全登录用户的应用程序。

可以使用以下两个标识服务之一:

  1. Azure AD 开发人员平台 (v1.0)。 也称 Azure AD v1 终结点,用于生成应用,方便用户使用 Microsoft 工作或学校帐户安全地登录。 有关详细信息,请参阅面向开发人员的 Azure Active Directory (v1.0) 概述
  2. Microsoft 标识平台 (v2.0)。 也称 Azure AD v2 终结点,这是 Azure AD 平台(1.0 版)的演进版。 可以通过它来生成应用程序,以便登录到所有 Microsoft 标识提供者,并获取令牌来调用 Microsoft API(例如 Microsoft Graph 或开发人员生成的其他 API)。 有关详细信息,请参阅 Microsoft 标识平台 (v2.0) 概述

若要了解 v1 和 v2 终结点的差异,请参阅为什么要更新到 Microsoft 标识平台 (v2.0)?。 如需完整信息,请参阅 Microsoft 标识平台(以前称为面向开发人员的 Azure Active Directory)

创建Azure AD标识提供者

本部分演示如何创建一个Azure AD OAuth 2.0 对机器人进行身份验证的标识提供者。 可以使用 Azure AD v1 或 Azure AD v2 终结点。

提示

你需要在租户中创建和注册 Azure AD 应用程序,在租户中你可以同意应用程序请求的委托权限。

  1. 在 Microsoft Azure 门户中打开 Azure Active Directory 面板。 如果未在正确的租户中,请选择 "切换目录 "以切换到正确的租户。 (有关创建租户的说明,请参阅访问门户并创建租户。)

  2. 打开“应用注册”面板。

  3. "应用注册 面板中,选择"新建注册"。

  4. 填写必填字段并创建应用注册。

    1. 命名应用程序。

    2. 为应用程序选择“支持的帐户类型”。 (这些选项中的任何一个都可以用于此示例。)

    3. 对于“重定向 URI”

      1. 选择“Web”。
      2. 将 URL 设置为 https://token.botframework.com/.auth/web/redirect
    4. 选择“注册” 。

      • 创建应用以后,Azure 会显示应用的“概览”页。
      • 记录“应用程序(客户端) ID”值。 稍后在创建连接字符串并使用机器人注册 注册 Azure AD提供程序时,将使用此值作为客户端 ID。
      • 另请记录“目录(租户) ID”值。 你还将使用它向机器人注册此提供程序应用程序。
  5. 在导航窗格中,选择" 证书&机密 ",为应用程序创建机密。

    1. 在“客户端机密”下,选择“新建客户端密钥” 。
    2. 添加一项说明,用于将此机密与可能需要为此应用创建的其他机密(例如 bot login)区别开来。
    3. 将“过期”设置为“永不”。
    4. 选择 添加
    5. 在离开此页面之前,记录该机密。 稍后在将 Azure AD 应用程序注册到机器人时,需将此值用作“客户端机密”。
  6. 在导航窗格中,选择 "API 权限 "以打开 "API 权限" 面板。 最佳做法是为应用显式设置 API 权限。

    1. 选择 "添加权限 "以显示" 请求 API 权限" 窗格。

    2. 对于此示例,请选择“Microsoft API”和“Microsoft Graph”。

    3. 选择“委托的权限”,确保选中所需权限。 本示例需要这些权限。

      备注

      标记为“需要管理员同意”的任何权限都需要用户和租户管理员登录,因此对于机器人来说,请尽量避免这些操作。

      • openid
      • profile
      • Mail.Read
      • Mail.Send
      • User.Read
      • User.ReadBasic.All
    4. 选择“添加权限”。 (用户首次通过机器人访问此应用时,需授予许可。)

现在已完成 Azure AD 应用程序的配置。

备注

创建连接字符串并向机器人注册注册标识提供程序时,会将 应用程序 (客户端) ID客户端机密。 请参阅下一节。

向机器人注册 Azure AD 标识提供者

下一步是在机器人中注册刚创建的 Azure AD 应用程序。

  1. Azure 门户中打开机器人的 Azure 机器人资源页。

  2. 选择“设置”。

  3. 在靠近页面底部的 " OAuth 连接设置" 下,选择 "添加设置"。

  4. 按如下所示填写表单:

    1. Name。 输入连接的名称。 在机器人代码中会用到。

    2. 服务提供商。 选择 Azure Active Directory v2。 选择该选项后,将显示特定于 Azure AD 的字段。

    3. 客户端 id。输入为 Azure AD v2 标识提供者记录的应用程序 (客户端) ID。

    4. 客户端密码。 输入为 Azure AD v2 标识提供者记录的机密。

    5. 标记 Exchange URL。 将其留空,因为它仅用于 Azure AD v2 中的 SSO。

    6. 租户 ID。 输入先前为 Azure AD 应用记录的 目录 (租户) ID ,或根据 创建 Azure DD 应用时选择的支持帐户类型,输入该目录。 若要确定分配哪个值,请遵循以下条件:

      • 创建 Azure AD 应用时,如果你 在此组织目录中 选择了 "仅限仅限 Microsoft (的帐户") ,请输入之前为 Azure AD 应用记录的 租户 ID
      • 但是,如果在任何 组织目录中选择了 "帐户" (任何 Azure AD 目录-多租户和个人 Microsoft 帐户,如 Xbox、Outlook .com)任何组织目录中的帐户 (Microsoft Azure AD directory-多租户) 中,请输入词语 common 而不是租户 ID。 否则,Azure AD 应用将验证已选择 ID 的租户,并排除个人 MS 帐户。

      此租户将与可进行身份验证的用户相关联。 有关详细信息,请参阅 Azure Active Directory 中的租户

    7. 对于 " 作用域",请输入你从应用程序注册中选择的权限的名称。 出于测试目的,可以只输入: openid profile

      备注

      对于 Azure AD v2,“作用域”字段的值区分大小写,以空格分隔。

  5. 选择“保存”。

备注

这些值让应用程序可以通过 Microsoft Graph API 访问 Office 365 数据。 此外,“令牌交换 URL”应留空,因为它仅用于 Azure AD v2 中的 SSO。

测试连接

  1. 选择 "连接" 条目以打开刚刚创建的连接。
  2. 选择 服务提供程序连接设置 窗格顶部的 "测试连接"。
  3. 第一次进行此操作时,应该会打开一个新的浏览器选项卡(其中列出了应用请求的权限)并提示你接受。
  4. 选择“接受”。
  5. 然后,此操作应该会将你重定向到“<your-connection-name> 的连接测试成功”页。

现在可以在机器人代码中使用此连接名称检索用户令牌。

准备机器人代码

需要机器人的应用 ID 和密码才能完成此过程。

  1. 从 github 存储库克隆要使用的示例:机器人身份验证机器人身份验证 MSGraph

  2. 更新 appsettings.json

    • ConnectionName 设置为要添加到机器人的 OAuth 连接设置的名称。

    • MicrosoftAppIdMicrosoftAppPassword 设置为机器人的应用 ID 和应用机密。

      根据机器人机密中的字符,可能需要 XML 转义密码。 例如,任何连字符 (&) 都需要编码为 &amp;

    {
      "MicrosoftAppType": "",
      "MicrosoftAppId": "",
      "MicrosoftAppPassword": "",
      "MicrosoftAppTenantId": "",
      "ConnectionName": ""
    }
    
  3. 更新 启动 .cs

    若要在 非公共 Azure 云中(如政府云)中使用 OAuth,必须在文件中添加以下代码 startup.cs

    string uri = "https://api.botframework.azure.us";
    MicrosoftAppCredentials.TrustServiceUrl(uri);
    OAuthClientConfig.OAuthEndpoint = uri;
    

若要获取 microsoft 应用 IDmicrosoft 应用密码 值,请参阅 获取注册密码

备注

你现在可以将此 bot 代码发布到你的 Azure 订阅 (在项目上选择 "发布" 并选择 " 发布) ,但这并不是本文所必需的。 需要设置一个发布配置,以便使用在 Azure 门户中配置机器人时使用的应用程序和托管计划。

使用 Emulator 测试机器人

安装 Bot Framework Emulator(如果尚未安装)。 另请参阅用 Emulator 进行调试

为了使机器人示例登录正常工作,必须配置 Emulator,如配置用于身份验证的 Emulator中所示。

测试

配置身份验证机制后,你可以执行实际的机器人示例测试。

备注

考虑到机器人示例的实现方式,系统可能会要求你输入幻码。 此幻码是 RFC#7636 的一部分,用于添加额外的安全元素。 删除幻码会增加安全风险。 可以使用启用了增强身份验证的直接连线来缓解此情况。 有关详细信息,请参阅 机器人 Framework 增强的身份验证

  1. 在计算机本地运行机器人示例。
  2. 启动模拟器。
  3. 在连接到机器人时,需提供机器人的应用 ID 和密码。
    • 你可从 Azure 应用注册获取应用 ID 和密码。 这些值与你在 appsettings.json.env 文件中分配给机器人应用的值相同。 在 Emulator 中,可以在配置文件中或首次连接到 bot 时分配这些值。
    • 如果以前需要对机器人代码中的密码进行 XML 转义,则还需在此处进行该操作。
  4. 键入 help 查看机器人的可用命令列表,然后测试身份验证功能。
  5. 登录后,在注销前都无需再次提供凭据。
  6. 要注销并取消身份验证,请键入 logout

备注

机器人身份验证要求使用机器人连接器服务。 服务从 Azure 机器人资源访问信息。

身份验证示例

机器人身份验证 示例中,此对话被设计为在用户登录后检索用户令牌。

身份验证机器人测试映像

身份验证 MSGraph 示例

机器人身份验证 MSGraph 示例中,此对话被设计为在用户登录后接受有限的一组命令。

msgraph 机器人测试映像


其他信息

如果用户要求机器人执行某项操作,而该操作要求机器人让用户登录,则机器人可以使用 OAuthPrompt 来开始检索给定连接的令牌。 OAuthPrompt 创建一个令牌检索流,其中包含:

  1. 查看 Azure 机器人服务是否已经有一个适用于当前用户和连接的令牌。 如果有令牌,则会返回令牌。
  2. 如果 Azure Bot 服务没有已缓存的令牌, OAuthCard 则会创建一个用户可选择的登录按钮。
  3. 用户选择 " OAuthCard 登录" 按钮后,Azure 机器人服务将直接向机器人发送用户令牌,或向用户显示一个6位数的身份验证代码,以便在聊天窗口中输入。
  4. 如果 Azure 机器人服务向用户提供身份验证代码,则机器人会用此身份验证代码来交换获取用户的令牌。

以下部分描述示例如何执行某些常见的身份验证任务。

使用 OAuth 提示来登录用户并获取令牌

体系结构 csharp 映像

Dialogs\MainDialog.cs

将 OAuth 提示添加到其构造函数中的 MainDialog。 在这里,连接名称的值已从 appsettings.json 文件中检索。

AddDialog(new OAuthPrompt(
    nameof(OAuthPrompt),
    new OAuthPromptSettings
    {
        ConnectionName = ConnectionName,
        Text = "Please Sign In",
        Title = "Sign In",
        Timeout = 300000, // User has 5 minutes to login (1000 * 60 * 5)
    }));

在对话步骤中,请使用 BeginDialogAsync 来启动 OAuth 提示,该提示要求用户登录。

  • 如果用户已登录,则会在不提示用户的情况下生成一个令牌响应事件,
  • 否则会提示用户登录。 Azure 机器人服务会在用户尝试登录后发送令牌响应事件。
return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);

在以下对话步骤中,检查上一步的结果中是否存在令牌。 如果该令牌不为 null,则表明用户已成功登录。

// Get the token from the previous step. Note that we could also have gotten the
// token directly from the prompt itself. There is an example of this in the next method.
var tokenResponse = (TokenResponse)stepContext.Result;

等待 TokenResponseEvent

启动 OAuth 提示时,它会等待令牌响应事件,目的是从中检索用户的令牌。

Bots\AuthBot.cs

AuthBot 派生自 ActivityHandler,会显式处理令牌响应事件活动。 在这里,我们会继续活动对话,这样 OAuth 提示就能处理事件并检索令牌。

protected override async Task OnTokenResponseEventAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
    Logger.LogInformation("Running dialog with Token Response Event Activity.");

    // Run the Dialog with the new Token Response Event Activity.
    await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}

注销用户

最佳做法是让用户显式注销,而不是依赖连接来退出。

Dialogs\LogoutDialog.cs

private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken = default(CancellationToken))
{
    if (innerDc.Context.Activity.Type == ActivityTypes.Message)
    {
        var text = innerDc.Context.Activity.Text.ToLowerInvariant();

        if (text == "logout")
        {
            // The UserTokenClient encapsulates the authentication processes.
            var userTokenClient = innerDc.Context.TurnState.Get<UserTokenClient>();
            await userTokenClient.SignOutUserAsync(innerDc.Context.Activity.From.Id, ConnectionName, innerDc.Context.Activity.ChannelId, cancellationToken).ConfigureAwait(false);

            await innerDc.Context.SendActivityAsync(MessageFactory.Text("You have been signed out."), cancellationToken);
            return await innerDc.CancelAllDialogsAsync(cancellationToken);
        }
    }

    return null;
}

添加 Teams 身份验证

OAuth 的处理方式与其他通道Teams稍有不同。 C#Teams JavaScript或) Java (中的 Teams 身份验证机器人示例演示了如何正确Teams。

其他通道和 Teams 的一个区别是,Teams 向机器人发送调用活动而不是事件活动。

Bots/TeamsBot.cs

protected override async Task OnTeamsSigninVerifyStateAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
{
    Logger.LogInformation("Running dialog with signin/verifystate from an Invoke Activity.");

    // The OAuth Prompt needs to see the Invoke Activity in order to complete the login process.

    // Run the Dialog with the new Invoke Activity.
    await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}

如果使用 OAuth 提示,则必须将此调用活动转发给对话。 我们将在 TeamsActivityHandler 中这样做。 将以下代码添加到主对话文件。

Bots/DialogBot.cs

public class DialogBot<T> : TeamsActivityHandler where T : Dialog

最后,请确保为 C# 机器人 (TeamsActivityHandler JavaScript 机器人添加适当的文件) 机器人文件夹的最顶层 TeamsActivityHandler.cs teamsActivityHandler.js

TeamsActivityHandler 也发送消息回应活动。 消息回应活动使用“回复到 ID”字段来引用原始活动。 此活动也应该能够在 Microsoft Teams 中通过活动源来查看。

备注

需要创建一个清单并在 validDomains 节中包含 token.botframework.com;否则,单击 OAuthCard“登录”按钮不会打开身份验证窗口。 使用 App Studio 生成清单。

进一步阅读