为基于 API 的消息扩展启用 SSO
基于 API 的消息扩展的单一登录 (SSO) 身份验证方法使用应用用户的 Teams 标识来向他们提供对应用的访问权限。 登录到 Teams 的用户无需在 Teams 环境中再次登录到你的应用。 Microsoft Entra SSO,应用能够以无提示方式获取由 Microsoft Entra 为其资源颁发的用户令牌。 然后,应用可以在未经用户同意的情况下对此令牌进行身份验证并检索用户配置文件信息。
先决条件
在开始之前,请确保具有以下各项:
- 具有活动订阅的 Azure 帐户。
- 基本熟悉Microsoft Entra ID和 Teams 应用开发。
下图显示了当 Teams 应用用户尝试访问基于 API 的消息扩展应用时 SSO 的工作原理:
- 用户在 Teams 中调用基于 API 的消息扩展应用,并调用需要身份验证的命令。
- 应用使用应用 ID 和所需范围向 Teams 后端服务发送请求 (
access_as_user
) 。 - Teams 后端服务会检查用户是否同意应用和范围。 如果未显示,则向用户显示一个同意屏幕。
- 如果用户同意,Microsoft Entra为用户和应用生成访问令牌,并将其发送到请求的授权标头中的应用。
- 应用验证令牌并从令牌中提取用户信息,例如名称、电子邮件和对象 ID。
- 身份验证成功后,将向用户授予对基于 API 的消息扩展的访问权限。
若要为基于 API 的消息扩展启用 SSO 身份验证,请执行以下步骤:
在 Microsoft Entra ID 中注册新应用
在 Web 浏览器上打开 Azure 门户。
选择 应用注册 图标。
将显示 应用注册 页。
选择 + 新建注册 图标。
将显示注册应用程序页。
输入要显示给应用用户的应用名称。 如果需要,可以在稍后阶段更改名称。
选择可以访问应用的用户帐户的类型。 可以从组织目录中的单租户或多租户选项中进行选择,也可以限制对个人Microsoft帐户的访问权限。
支持的帐户类型的选项
选项 选择此选项可... 此组织目录中的帐户仅 (Microsoft - 单租户) 生成仅供租户中(或来宾)用户使用的应用程序。
此应用通常称为为组织 (LOB 应用) 构建的自定义应用,是Microsoft 标识平台中的单租户应用程序。任何组织目录中的帐户 (任何Microsoft Entra ID租户 - 多租户) 允许任何Microsoft Entra租户中的用户使用应用程序。 例如,如果要生成 SaaS 应用程序,并且打算将其提供给多个组织,则此选项适用。
这种类型的应用在Microsoft 标识平台称为多租户应用程序。任何组织目录中的帐户 (任何Microsoft Entra ID租户 - 多租户) 和个人Microsoft帐户 (,例如Skype、Xbox) 面向最广泛的客户集。
通过选择此选项,你将注册一个多租户应用程序,该应用程序可以支持具有个人Microsoft帐户的应用用户。仅限个人 Microsoft 帐户 仅为拥有个人 Microsoft 帐户的用户生成应用程序。 注意
无需输入 重定向 URI 即可为基于 API 的消息扩展应用启用 SSO。
选择“注册”。 浏览器上弹出一条消息,指出应用已创建。
将显示包含应用 ID 和其他应用详细信息的页面。
记下并保存 应用程序 (客户端中的应用 ID) ID ,以便稍后更新应用清单。
你的应用已在 Microsoft Entra ID 中注册。 现在,你已获得基于 API 的消息扩展应用的应用 ID。
配置访问令牌的范围
创建新的应用注册后,配置范围 (权限) 选项,以便将访问令牌发送到 Teams 客户端,以及授权受信任的客户端应用程序启用 SSO。
若要配置作用域并授权受信任的客户端应用程序,必须:
- 添加应用 ID URI:为应用配置范围 (权限) 选项。 公开 Web API 并配置应用 ID URI。
- 配置 API 范围:定义 API 的范围,以及可以同意范围的用户。 只能让管理员为特权较高的权限提供许可。
- 配置授权客户端应用程序:为要预授权的应用程序创建授权客户端 ID。 它允许应用用户访问你配置的应用范围(权限),而无需任何进一步的同意。 仅预授权你信任的客户端应用程序,因为应用用户没有机会拒绝同意。
App ID URI
从左窗格中选择“管理>公开 API”。
随即显示“公开 API”页。
选择“ 添加 ”,以以 的形式
api://{AppID}
生成应用 ID URI。此时会显示用于设置应用 ID URI 的部分。
按此处介绍的格式输入 应用程序 ID URI 。
-
应用程序 ID URI 预填充了应用 ID (GUID) 格式
api://{AppID}
。 - 应用 ID URI 格式必须为:
api://fully-qualified-domain-name.com/{AppID}
。 - 在
api://
和{AppID}
之间出入fully-qualified-domain-name.com
(即 GUID)。 例如,api://example.com/{AppID}。
重要
- 如果要生成独立机器人,请输入应用 ID URI 作为 api://botid-{YourBotId}。 此处,{YourBotId} 是你的Microsoft Entra应用 ID。
- 如果要使用机器人、消息扩展和选项卡生成应用,请输入应用 ID URI 作为 api://fully-qualified-domain-name.com/botid-{YourClientId},其中 {YourClientId} 是机器人应用 ID。
- 如果要构建具有消息扩展或选项卡功能且没有机器人的应用,请输入应用 ID URI 作为 api://fully-qualified-domain-name.com/{YourClientId},其中 {YourClientId} 是你的Microsoft Entra应用 ID。
-
具有多个功能的应用的应用程序 ID URI:如果要生成基于 API 的消息扩展,请输入应用 ID URI 作为
api://fully-qualified-domain-name.com/{YourClientId}
,其中 {YourClientId} 是Microsoft Entra应用 ID。 - 域名的格式:仅对域名使用小写字母。
-
应用程序 ID URI 预填充了应用 ID (GUID) 格式
选择“保存”。
浏览器上弹出一条消息,指出应用 ID URI 已更新。
应用 ID URI 显示在页面上。
记下并保存应用 ID URI,以便稍后更新应用清单。
配置 API 范围
注意
- 基于 API 的消息扩展仅支持 access_as_user 范围。
- API 接收一个Microsoft Entra访问令牌,其范围设置为
access_as_user
Azure 门户 中注册。 但是,令牌无权调用任何其他下游 API,例如 Microsoft Graph。
在此 API 部分定义的“作用域”中选择“+ 添加作用域”。
将显示 “添加范围 ”页。
输入配置范围的详细信息。
- 输入范围名称。 此字段是必需的。
- 选择可以对此范围表示同意的用户。 默认选项为 仅限管理员。
- 输入管理员同意显示名称。 此字段是必需的。
- 输入管理员同意的说明。 此字段是必需的。
- 输入 用户同意显示名称。
- 输入用户同意说明。
- 为状态选择“启用”选项。
- 选择“添加作用域”。
浏览器上弹出一条消息,指出已添加范围。
定义的新范围显示在页面上。
配置授权的客户端应用程序
在 “公开 API ”页中转到 “授权的客户端应用程序 ”部分,然后选择“ + 添加客户端应用程序”。
将显示“添加客户端应用程序”页。
为要为应用的 Web 应用程序授权的应用程序输入相应的Microsoft 365 客户端 ID。
注意
适用于 Teams 的移动、桌面和 Web 应用的 Microsoft 365 个客户端 ID 是必须添加的实际 ID。
选择以下客户端 ID 之一:
使用客户端 ID 用于授权... 1fec8e78-bce4-4aaf-ab1b-5451cc387264 Teams 移动或桌面应用 5e3ce6c0-2b1f-4285-8d4b-75ee78787346 Teams Web 应用 选择在 “授权范围 ”中为应用创建的应用 ID URI,将范围添加到公开的 Web API。
选择“添加应用程序”。
浏览器上弹出一条消息,指出已添加授权的客户端应用。
授权应用的客户端 ID 显示在页面上。
注意
可以授权多个客户端应用程序。 重复此过程的步骤以配置另一个已授权的客户端应用程序。
已成功配置应用范围、权限和客户端应用程序。 确保记下并保存应用 ID URI。 接下来,配置访问令牌版本。
身份验证令牌
当消息扩展在身份验证期间调用 API 时,它会收到包含用户访问令牌的请求。 然后,消息扩展会将令牌添加到传出 HTTP 请求的授权标头中。 标头格式为 Authorization: Bearer <token_value>
。 例如,当消息扩展对需要身份验证的服务进行 API 调用时。 扩展按如下所示构造 HTTP 请求:
GET /api/resource HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
在基于 API 的消息扩展获取具有令牌的请求标头后,请执行以下步骤:
身份验证:验证受众、范围、颁发者和签名声明的令牌,以检查令牌是否适用于你的应用。 有关更多声明,请参阅 ID 令牌声明。
以下示例显示了 JSON Web 令牌 (带有标头和响应的 JWT) :
{ "typ": "JWT", "rh": "0.AhoAv4j5cvGGr0GRqy180BHbR6Rnn7s7iddIqxdA7UZsDxYaABY.", "alg": "RS256", "kid": "q-23falevZhhD3hm9CQbkP5MQyU" }.{ "aud": "00000002-0000-0000-c000-000000000000", "iss": "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47/v2.0", "iat": 1712509315, "nbf": 1712509315, "exp": 1712513961, "aio": "Y2NgYEjJqF0stqv73u41a6ZmxPEvBgA=", "azp": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", "azpacr": "0", "name": "John Doe", "oid": "00000000-0000-0000-0000-000000000000", "preferred_username": "john.doe@contoso.com", "rh": "I", "scp": "access_as_user", "sub": "e4uM7JgAEm08GBuasSltQjvPuMX1fR5TqxopJpqZJB8", "tid": "12345678-aaaa-bbbb-cccc-9876543210ab", "uti": "h7DMQwSPAEeiEe62JJUGAA", "ver": "2.0" }
使用令牌:从令牌中提取用户信息,例如名称、电子邮件和对象 ID,并使用令牌调用消息扩展应用自己的 API。 有关声明引用的详细信息以及访问令牌中包含的声明的详细信息,请参阅 访问令牌声明。
更新应用清单
更新应用清单文件中的以下属性:
webApplicationInfo
:属性webApplicationInfo
用于为应用启用 SSO,以帮助应用用户无缝访问基于 API 的消息扩展应用。 在 Microsoft Entra ID 中注册的应用 ID URI 配置了公开的 API 的范围。 有关详细信息,请参阅 webApplicationInfo。microsoftEntraConfiguration
:为应用启用 SSO 身份验证。 将supportsSingleSignOn
属性配置为true
以支持 SSO,并减少对多个身份验证的需求。 如果 属性设置为false
或留空,则用户无法将应用上传到 Teams,并且应用验证失败。
配置应用清单:
打开基于 API 的消息扩展应用。
打开应用清单文件夹。
注意
- 应用清单文件夹应位于应用文件夹的根目录中。 有关详细信息,请参阅 创建Microsoft Teams 应用包。
- 有关如何创建manifest.json的详细信息,请参阅 应用清单架构。
打开
manifest.json
文件。将以下代码片段添加到
webApplicationInfo
应用清单文件的 部分:"webApplicationInfo": { "id": "{Microsoft Entra AppId}", "resource": "api://subdomain.example.com/{Microsoft Entra AppId}" }
其中,
-
{Microsoft Entra AppId}
是在 Microsoft Entra ID 中注册应用时创建的应用 ID。 这是 GUID。 -
api://subdomain.example.com/{Microsoft Entra AppId}
是在 Microsoft Entra ID 中创建范围时注册的应用 ID URI。
-
将以下代码片段添加到
composeExtensions
应用清单文件的 部分:"authorization": { "authType": "microsoftEntra", “microsoftEntraConfiguration”: { “supportsSingleSignOn”: true } },
保存应用清单文件。
恭喜! 你已为基于 API 的消息扩展启用了 SSO。