制定委托权限策略

本文有助于开发者实施在应用程序中管理权限的最佳方法,并使用零信任原则进行开发。 如获取访问资源的授权所述,委托权限与委托访问一起使用,以允许应用程序代表用户执行操作,仅访问用户可以访问的内容。 应用程序权限用于直接访问,以允许应用程序访问与该权限关联的任何数据。 只有服务主体的管理员和所有者才能同意应用程序权限。

权限和同意模型主要指应用程序。 权限和同意流程无法控制用户可以执行的操作。 它控制的是允许应用程序执行的操作。

参考以下维恩图。 使用委托的权限时,用户可以执行的操作与允许应用程序执行的操作之间存在交集。 该交集是应用程序所绑定的有效权限。 每当使用委托权限时,有效权限都会对其进行约束。

维恩图显示了有效权限,即应用权限和用户能力之间的交集。

例如,在应用前面有用户的应用程序获得了更新租户中每个用户的配置文件的权限。 这并不意味着运行应用程序的任何人都能更新其他人的配置文件。 如果管理员决定授予应用程序 User.ReadWrite.All,则他们认为在更新任何用户配置文件时应用程序正在执行正确的操作。 你的应用可能会记录更改并正确地保护信息。 管理员对应用程序而非用户做出价值判断。

最低特权方法

API 可能很复杂。 简单的 API 可能没有许多操作。 复杂的 API(如 Microsoft Graph)封装了应用程序可能想要使用的许多请求。 仅仅因为应用程序有权读取并不意味着它应该有权更新。 例如,Microsoft Graph 有数千个 API。 如果只是因为你有权读取用户的个人资料,这不能成为你应该有权删除其所有 OneDrive 文件的理由。

作为开发人员,你应:

  • 知道应用调用哪些 API。
  • 了解 API 文档以及 API 所需的权限。
  • 使用可能最少的权限来完成任务。

API 通常提供对组织数据存储的访问权限,会吸引想要访问该数据的攻击者注意。

评估你所请求的权限,确保这些权限是完成工作而需要的绝对最低的一组特权。 避免请求更高的权限;相反,应当小心地处理 Microsoft Graph 等 API 提供的大量权限。 找到并使用最少的权限来满足你的需求。 如果不编写代码来更新用户的配置文件,则不会为应用程序请求它。 如果仅访问用户和组,则不会请求访问目录中的其他信息。 如果不编写访问用户电子邮件的代码,则不会请求管理用户电子邮件的权限。

在零信任应用程序开发中:

  • 定义应用程序的意图及其需求。
  • 确保不良参与者不能以你未打算的方式泄露和使用你的应用。
  • 发出批准请求,在其中定义要求(例如,读取用户的邮件)。

可以批准你的请求的人分为两个类别:始终可以同意权限请求的管理员和非管理员的普通用户。 但是,租户管理员在其租户中拥有关于哪些权限需要管理员同意以及用户可以同意哪些权限的最终决定权。

当 API 设计者要求管理员同意某项权限时,该权限始终需要管理员同意。 租户管理员不能拒绝,并且只需要用户同意。

当 API 设计者定义需要用户同意的权限时,租户管理员可以拒绝 API 设计者的用户同意建议。 租户管理员可以在租户中使用一个“大开关”执行此操作:所有内容都需要管理员同意。 他们可以通过权限和同意管理以更精细的方式推翻用户同意。 例如,他们可能允许用户同意来自已验证发布者的用户同意请求,但不允许来自其他发布者的请求。 在另一个示例中,他们可能允许 User.Read 以用户身份登录并读取其配置文件,但要求管理员同意请求邮件或文件权限的应用。

API 设计师提出建议,但租户管理员有最终决定权。 因此,作为开发者,你并不总是知道你的应用何时需要管理员同意。 最好围绕这一点进行规划和设计,但请记住,发出令牌请求时,可能会出于任何原因被拒绝。 在代码中,需要正常处理未获取令牌的事件,因为客户或用户在其中运行应用程序的租户管理员决定权限何时需要管理员同意。

使用 JavaScript MSAL 的示例

对于此示例中的身份验证,使用 JavaScript Microsoft 身份验证库 (MSAL) 在单页应用程序 (SPA) 中以用户身份登录,其中所有应用逻辑都从浏览器执行。

从相关的快速入门文章中,可以下载并运行代码示例。 它演示 JavaScript 单页应用程序 (SPA) 如何通过使用具有代码交换证明密钥 (PKCE) 的授权代码流让用户登录并调用 Microsoft Graph。 此代码示例显示如何获取访问令牌来调用 Microsoft Graph API 或任何 Web API。

如以下示例代码所示,实例化公共客户端,因为完全在浏览器中运行的应用程序必须是公共客户端。 当代码处在浏览器中时,用户可以掌握应用程序的内部。

// Create the main myMSALObj instance
// configuration parameters are located at authConfig.js
const myMSALObj = new msal.PublicClientApplication(msalConfig);

然后使用我们的 MSAL 库。 在 MSAL JavaScript 中,有一个要登录的特定 API。 浏览器内有两个利用特定功能的 API。 一个是使用弹出体验登录;另一个是使用浏览器重定向体验登录。

如以下代码示例所示,登录弹出项通过调用 signIn 函数来处理用户需要执行的身份验证。

function signIn() {

    /**
     * You can pass a custom request object. This overrides the initial configuration. For more information, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
     */

    myMSALObj.loginPopup(loginRequest)
        .then(handleResponse)
        .catch(error => {
            console.error(error);
        });
}

应用可以获取有关用户的信息,例如其显示名称或用户 ID。 接下来,你的应用需要授权才能从 Microsoft Graph 读取用户的完整配置文件,方法是遵循在整个 MSAL 库中使用的模式。

如以下示例代码所示,应用尝试通过调用 AcquireTokenSilent 获得授权。 如果 Microsoft Entra ID 可以颁发令牌而不与用户交互,则 AcquireTokenSilent 返回应用代表用户访问 Microsoft Graph 所需的令牌。

function getTokenPopup(request) {

    /**
     * See here for more info on account retrieval: 
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
     */
    request.account = myMSALObj.getAccountByUsername(username);
    
    return myMSALObj.`AcquireTokenSilent`(request)
        .catch(error => {
            console.warn("silent token acquisition fails. acquiring token using popup");
            if (error instanceof msal.InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return myMSALObj.`AcquireTokenPopup`(request)
                    .then(tokenResponse => {
                        console.log(tokenResponse);
                        return tokenResponse;
                    }).catch(error => {
                        console.error(error);
                    });
            } else {
                console.warn(error);
            }
    });
}

但是,Microsoft Entra ID 通常无法在不与用户交互的情况下颁发令牌(例如,用户更改了其密码或未授予同意)。 因此,AcquireTokenSilent 将错误发送回需要用户交互的应用程序。 当你的应用收到错误时,你将回退到调用 AcquireTokenPopup

此时,Microsoft Entra ID 与用户进行了对话,以便他们可以对用户进行身份验证并授权你的应用代表用户执行操作(例如,执行 MFA、提供其密码、授予同意)。 然后,你的应用将获得继续操作所需的令牌。

企业零信任之旅的主要步骤是采用更强大的身份验证方法,而不仅仅是用户 ID 和密码。 前面的示例代码完全使企业能够迁移到企业选择的更强大的身份验证方法。 例如,多重身份验证,使用 FIDO2 密钥的完全无密码化、Microsoft Authenticator。

后续步骤

  • 获取访问资源的授权有助于了解在获取应用程序的资源访问权限时如何最好地确保零信任。
  • 制定应用程序权限策略可帮助你确定应用程序权限凭据管理方法。
  • 自定义令牌介绍了可以在 Microsoft Entra 令牌中接收的信息。 它说明了如何自定义令牌以提高灵活性和控制度,同时提高最低特权下的应用程序零信任安全性。
  • 在令牌中配置组声明和应用角色介绍了如何使用应用角色定义来配置应用,以及如何将安全组分配给应用角色。 这些方法有助于提高灵活性和控制度,同时提高最低特权下的应用程序零信任安全性。
  • API 保护描述了通过注册保护 API、定义权限和同意,以及强制实施访问权限,以实现零信任目标的最佳做法。
  • 从另一个 API 调用 API 可帮助你在一个 API 需要调用另一个 API 时确保零信任,并在应用程序代表用户工作时安全地开发应用程序。
  • 授权最佳做法可帮助你为应用程序实现最佳授权、权限和同意模型。
  • 在应用程序开发生命周期中使用零信任身份和访问管理开发最佳做法来创建安全应用程序。