公共客户端和机密客户端应用程序

Microsoft 身份验证库 (MSAL) 定义两种类型的客户端;公共客户端和机密客户端。 客户端是一种软件实体,具有标识提供者分配的唯一标识符。 区分客户端类型的依据在于其使用授权服务器安全地进行身份验证的能力,以及其保存敏感标识证明信息,因此其访问范围内的用户无法访问或了解这些信息的能力。

公共客户端应用 机密客户端应用
Desktop app 桌面应用 Web app Web 应用
Browserless API 无浏览器 API Web API Web API
Mobile app 移动应用 Daemon/service 服务/守护程序

公共客户端和机密客户端授权

在检查给定客户端的公共或机密性质时,我们评估的是该客户端向授权服务器证明其标识的能力。 这一点非常重要,因为授权服务器必须能够信任客户端的标识才能颁发访问令牌。

  • 公共客户端应用程序在桌面、无浏览器 API、移动或客户端浏览器应用等设备上运行。 不能信任它们安全地保守应用程序机密,因为它们只能代表用户访问 Web API。 只要给定应用的源或已编译字节码在可以读取、反汇编或由不受信任方检查的任何位置传输,它都是公共客户端。 由于它们还仅支持公共客户端流,并且不能保存配置时机密,因此它们不能拥有客户端密码。

  • 机密客户端在服务器上,例如如 Web 应用、Web API 应用,或服务/守护程序应用。 它们被认为难以被用户或攻击者访问,因此可以充分保存配置时机密来断言其身份证明。 客户端 ID 通过 Web 浏览器公开,但机密仅在传回通道中传递,永远不会直接公开。

机密及其在证明身份方面的重要性

下面是客户端如何向授权服务器证明其身份的一些示例:

  • Azure 资源的托管标识 - 对于仅限应用的身份验证场景,在 Azure 上构建的应用程序和服务开发人员可以选择将机密管理、轮换和保护卸载到平台本身。 使用托管标识时,将使用 Azure 资源提供和删除标识,并且任何人(包括全局管理员)均无法访问基础凭据。 通过使用托管标识,可以防止泄露机密的风险,并支持提供程序为你处理安全性。
  • 客户端 ID 和机密 - 在此模式中,注册客户端时授权服务器会生成一对值。 客户端 ID 是标识应用程序的公共值,而客户端密码则是用于证明应用程序标识的机密值。
  • 证明持有证书 - 公钥基础结构 (PKI)(包括 X.509 等标准)是一种基本技术,可实现通过 Internet 进行安全通信,并且是 Internet 隐私的支柱。 PKI 用于颁发数字证书,可用于验证参与在线通信各方的标识,并且是支持 HTTPS 等协议,广泛用于保护 Web 流量的基础技术。 同样,证书可用于在 Azure 中通过实现服务之间的相互身份验证来保护服务到服务 (S2S) 通信。 这包括了通过向其他服务提供证书来证明其标识的每项服务。
  • 提供已签名断言 - 已签名断言用于工作负荷标识联合,可使受信任的第三方标识提供者令牌与 Microsoft 标识平台交换,以获取调用 Microsoft Entra ID 受保护资源的访问令牌。 工作负载标识联合可用于实现各种联合方案,包括 Azure Kubernetes 服务、Amazon Web Services EKS、GitHub Actions 等。

证明客户端标识何时会非常重要?

在授予对敏感数据或资源的访问权限之前,如果需要验证客户端应用程序的真实性和授权,则证明客户端标识会非常重要。 示例包括:

  • 控制 API 访问 - 如果你有计量流量(例如用于计费)或者公开了敏感数据或资源的 API,你将在授予访问权限之前验证客户端的身份。 例如,在确保只有经过授权的应用程序有权访问 API,并确保按计量 API 使用情况对正确客户计费时,这一点非常重要。
  • 保护用户免遭假冒应用欺骗 - 如果你有一个服务部署、面向用户的应用程序(例如后端驱动的 Web 应用)可访问敏感数据或服务,使用客户端机密来保护该应用程序使用的资源,可以防止居心不良的人通过假冒合法客户端来钓鱼用户并窃取数据或滥用访问权限。
  • S2S 通信 - 如果有多个需要相互通信的后端服务(例如下游 API),可以验证每个服务的身份,确保它们仅有权访问执行其功能所需的资源。

一般情况下,证明客户端标识在需要对与用户无关或除用户以外的客户端进行身份验证和授权时非常重要。

机密客户端:管理机密的最佳做法

使用托管标识来简化部署和安全 - 托管标识会在 Microsoft Entra ID 中为应用程序提供一个自动托管标识,以便在连接到支持 Microsoft Entra ID 身份验证的资源时使用。 应用程序可以使用托管标识来获取 Microsoft Entra ID 仅应用令牌,而无需管理任何凭据。 这可以消除与机密管理相关的许多复杂工作,同时提高安全性和复原能力。 如果使用托管标识,则已为你考虑到以下大部分(如果不是全部)最佳做法。

使用安全存储 - 将客户端机密存储在安全位置,例如密钥保管库加密配置文件 避免将客户端密码以纯文本形式或作为签入文件存储到版本控制系统。

限制访问 - 将对客户端密码的访问限制为仅授权人员。 使用基于角色的访问控制将对客户端密码的访问限制为仅需要使用其执行其操作职责的人员。

轮换客户端机密 - 根据需要或计划轮换客户端机密,可以最大限度地降低已泄露机密被用于获取未经授权的访问的风险。 应用该做法后,建议继续使用密钥的时间跨度会受到所用加密算法强度,以及/或对标准或法规合规性做法的遵循情况的影响。

使用长机密和强加密 - 这与上一点密切相关,对传输中(在网络上)和静态(磁盘上)的数据使用强加密算法,有助于确保高熵机密不太可能被暴力破解。 AES-128(或更高版本)等算法可以帮助保护静态数据,而 RSA-2048(或更高版本)可帮助有效保护传输中的数据。 由于网络安全的不断发展,咨询安全专家并定期审查算法选择始终是最佳做法。

避免硬编码机密 - 不要在源代码中硬编码客户端密码。 避免源代码中的机密可以最大程度地降低获取源代码访问权限的不良行动者的意义。 它还可以防止此类机密被意外推送到不安全的存储库,或提供给可能具有源访问权限但无权访问机密的项目参与者。

监视存储库,防止机密泄漏 - 很不幸,处理源代码时会发生错误签入。 Git 预提交挂钩是防止意外签入的一种建议方法,但不能替代监视。 自动监视存储库可以识别泄露的机密,通过制定计划来轮换被盗用凭据,可以帮助减少安全事件。

监视可疑活动 - 监视日志和审核线索,查找与客户端密码相关的可疑活动。 尽可能使用自动警报和响应流程来通知人员,并定义适用于与客户端密码相关的异常活动的应变措施。

构建应用程序时考虑客户端保密性 - 安全模型的强度取决于链条中最薄弱的环节。 不要将安全凭据或令牌从机密转发到公共客户端,因为这可能会将客户端密码数据移动到公共客户端,从而允许假冒机密客户端。

使用来自受信任源的最新库和 SDK - Microsoft 标识平台提供各种客户端和服务器 SDK 和中间件,用于在提高工作效率的同时保护应用程序的安全。 Microsoft.Identity.Web等库简化了在 Microsoft 标识平台上向 Web 应用和 API 添加身份验证和授权的操作。 保持依赖项处于最新状态有助于确保应用程序和服务受益于最新的安全创新和更新。

比较客户端类型及其功能

下面是公共客户端和机密客户端应用之间的一些相似之处和差异:

  • 两种应用类型都可以维护用户令牌缓存,并且可以通过无提示方式获取令牌(当缓存中存在令牌)。 机密客户端应用还为应用本身获取的令牌提供应用令牌缓存。
  • 两种应用类型都可以管理用户帐户,并可以从用户令牌缓存中获取帐户、从其标识符中获取帐户,或移除帐户。
  • 在 MSAL 中,公共客户端应用可使用四种方法通过单独的身份验证流获取令牌。 机密客户端应用只能使用三种方法来获取令牌,还可使用一种方法来计算标识提供者授权终结点的 URL。 客户端 ID 会在构建应用程序时传递一次,而在应用获取令牌时无需再次传递。 有关详细信息,请参阅《获取令牌》。

公共客户端可用于启用对受保护资源的用户委托访问权限,但无法证明自己的应用程序标识。 另一方面,机密客户端可以同时执行用户和应用程序身份验证和授权,并且在构建时必须考虑到安全性,以确保不会与公共客户端或其他第三方共享其机密。

在某些情况下(例如 S2S 通信),托管标识等基础结构极大地有助于简化服务的开发和部署,并消除通常与机密管理相关的许多复杂工作。 当无法使用托管标识时,请务必制定策略、预防措施和应急措施来保护机密,并应对与其相关的安全事件。

另请参阅

有关应用程序配置和实例化的详细信息,请参阅: