Microsoft 标识平台中的范围和权限
Microsoft 标识平台实现 OAuth 2.0 授权协议。 OAuth 2.0 是可让第三方应用代表用户访问 Web 托管资源的方法。 与 Microsoft 标识平台集成的任何 Web 托管资源都有一个资源标识符(也称为“应用程序 ID URI”)。
在本文中,你将了解标识平台中的范围和权限。
以下列表显示了 Microsoft Web 托管资源的一些示例:
- Microsoft Graph:
https://graph.microsoft.com
- Microsoft 365 邮件 API:
https://outlook.office.com
- Azure Key Vault:
https://vault.azure.net
这同样适用于已与 Microsoft 标识平台集成的任何第三方资源。 这些资源还可以定义一组可用于将该资源的功能分成较小区块的权限。 例如, Microsoft Graph 已定义执行以下任务及其他任务所需的权限:
- 读取用户的日历
- 写入用户的日历
- 以用户身份发送邮件
由于存在这些类型的权限定义,因此资源可以更精细地控制其数据以及 API 功能的公开方式。 第三方应用可以从用户和管理员请求这些权限,只有在用户或管理员批准该请求之后,应用才能代表用户访问或处理数据。
将资源的功能分割成小的权限集时,可将第三方应用构建为只请求执行其功能所需的权限。 用户和管理员能够知道应用可以访问哪些数据, 因此可以更加确信应用不会出现恶意行为。 开发人员应始终遵守“最低特权”原则,仅请求分配正常运行应用程序所需的权限。
在 OAuth 2.0 中,这些类型的权限集称为“范围”。 它们通常也称为“权限”。 在 Microsoft 标识平台中,权限以字符串值形式表示。 应用通过在 scope
查询参数中指定权限来请求所需的权限。 标识平台支持多个定义明确的 OpenID Connect 范围以及基于资源的权限(通过将权限值追加到资源的标识符或应用程序 ID URI 来指示每个权限)。 例如,权限字符串 https://graph.microsoft.com/Calendars.Read
用于请求在 Microsoft Graph 中读取用户日历的权限。
在对 Microsoft 标识平台的授权服务器的请求中,如果在 scope 参数中省略资源标识符,则假定资源为 Microsoft Graph。 例如,scope=User.Read
等效于 https://graph.microsoft.com/User.Read
。
管理员限制的权限
Microsoft 标识平台中的权限可以设置为受管理员限制。 例如,许多更高特权的 Microsoft Graph 权限需要管理员批准。 如果你的应用需要受管理员限制的权限,则组织的管理员必须代表组织的用户同意这些范围。 以下部分提供了这些权限类型的示例:
User.Read.All
:读取所有用户的完整配置文件Directory.ReadWrite.All
:将数据写入组织的目录Groups.Read.All
:读取组织目录中的所有组
注意
在对 Microsoft 标识平台的授权、令牌或同意终结点请求中,如果在 scope 参数中省略资源标识符,则假定资源为 Microsoft Graph。 例如,scope=User.Read
等效于 https://graph.microsoft.com/User.Read
。
尽管使用者用户可以授予应用程序对此类数据的访问权限,但组织用户无法授予对同一公司敏感数据集的的访问权限。 如果应用程序向组织用户请求访问以下权限之一,用户会收到错误消息,指出他们未经授权,无法许可应用的权限。
如果应用程序请求应用程序权限,并且管理员授予了这些权限,则不会代表任何特定用户进行此授权。 而是直接为客户端应用程序授予权限。 这些类型的权限应仅由守护程序服务以及后台运行的其他非交互式应用程序使用。 有关直接访问方案的详细信息,请参阅 Microsoft 标识平台中的访问方案。
有关如何在 Web API 中公开范围的分步指南,请参阅配置应用程序以公开 Web API。
OpenID Connect 范围
OpenID Connect 的 Microsoft 标识平台实现具有一些已明确定义并托管在 Microsoft Graph 上的范围:openid
、email
、profile
和 offline_access
。 不支持 address
和 phone
OpenID Connect 范围。
如果请求 OpenID Connect 范围和令牌,你会获得一个用于调用 UserInfo 终结点的令牌。
openid
范围
如果应用使用 OpenID Connect 登录,它必须请求 openid
范围。 openid
范围作为“登录”权限显示在工作帐户同意页上。
应用可使用此权限以 sub
声明的形式接收用户的唯一标识符。 此权限还会向应用提供对 UserInfo 终结点的访问权限。 可以在 Microsoft 标识平台令牌终结点上使用 openid
范围来获取 ID 令牌。 应用可以使用这些令牌进行身份验证。
email
范围
email
范围可与 openid
范围以及任何其他范围一起使用。 它以 email
声明的形式向应用提供对用户主要电子邮件地址的访问权限。
仅当某个电子邮件地址与用户帐户相关联(并非总是如此)时, email
声明才包含在令牌中。 如果应用使用 email
范围,则应用需要能够处理令牌中不存在 email
声明的情况。
profile
范围
profile
范围可与 openid
范围以及任何其他范围一起使用。 它向应用提供对大量有关该用户的信息的访问权限。 可访问的信息包括但不限于用户的名字、姓氏、首选用户名和对象 ID。
有关特定用户的 id_tokens
参数中提供的 profile
声明的完整列表,请参阅 id_tokens
参考。
offline_access
范围
offline_access
范围 可让应用长时间代表用户访问资源。 在同意页上,此范围显示为“维持对已授予访问权限的数据的访问权限”权限。
用户批准 offline_access
范围后,应用可接收来自 Microsoft 标识平台令牌终结点的刷新令牌。 刷新令牌的生存期较长。 旧的访问令牌过期时,应用可以获取新的访问令牌。
注意
目前,此权限会出现在所有同意页上,即使对于那些不提供刷新令牌的流(例如隐式流),也是这种情况。 该设置解决的是此类情况:客户端可以从隐式流开始,然后转到需要刷新令牌的代码流。
在 Microsoft 标识平台上(向 v2.0 终结点发出的请求),应用程序必须显式请求 offline_access
范围才能接收刷新令牌。 因此,在 OAuth 2.0 授权代码流中兑换授权代码时,你只会收到来自 /token
终结点的访问令牌。
访问令牌有效期通常约为一小时。 此时,应用需要将用户重定向回到 /authorize
终结点,以请求新的授权代码。 在此重定向期间,根据应用类型,用户可能需要再次输入其凭据或再次同意权限。
刷新令牌的到期时间比访问令牌长,通常有效期为一天。 有关如何获取及使用刷新令牌的详细信息,请参阅 Microsoft 标识平台协议参考。
在响应中包含刷新令牌可能取决于几个因素,包括应用程序的特定配置和授权过程中请求的范围。 如果希望在响应中收到刷新令牌但失败,请考虑以下因素:
- 范围要求:确保请求
offline_access
范围以及其他任何必要的范围。 - 授权授权类型:使用授权代码授予类型时通常提供刷新令牌。 如果流不同,则可能会影响响应。
- 客户端配置:在标识平台中检查应用程序的设置。 某些配置可能会限制refresh_tokens的颁发。
.default
范围
.default
范围通常用于在请求中引用资源服务 (API),而无需标识特定权限。 如果需要征得同意,请使用 .default
信号,应会提示同意应用程序注册中列出的所有必需权限(适用于列表中的所有 API)。
范围参数值是使用资源的标识符 URI 和 .default
构造的,并用正斜杠 (/
) 分隔。 例如,如果资源的标识符 URI 为 https://contoso.com
,则请求的范围为 https://contoso.com/.default
。 有关必须包含另一个斜杠才能正确请求令牌的情况,请参阅有关尾随斜杠的部分。
使用 scope={resource-identifier}/.default
在功能上与 v1.0 终结点上的 resource={resource-identifier}
相同(其中,{resource-identifier}
是 API 的标识符 URI,例如 Microsoft Graph 的 https://graph.microsoft.com
)。
.default
范围可用于任何 OAuth 2.0 流,并可发起管理员同意。 它在代理流和客户端凭据流中是必需的。
客户端不能在单个请求中合并静态同意 (.default
) 和动态同意。 因此 scope=https://graph.microsoft.com/.default Mail.Read
会导致错误,因为它合并了范围类型。
用户已授予同意时为 .default
.default
scope 参数仅当在客户端和资源之间代表登录用户授予了任何委托的权限时,才会触发同意提示。
如果同意存在,则返回的令牌将包含已登录用户授予该资源的所有范围。 但是,如果没有为请求的资源授予任何权限(或者如果已提供 prompt=consent
参数),则会为在客户端应用程序注册上为列表中的所有 API 配置的所有必需权限显示同意提示。
例如,如果请求的范围为 https://graph.microsoft.com/.default
,你的应用程序将请求 Microsoft Graph API 的访问令牌。 如果为代表已登录用户的 Microsoft Graph 授予了至少一个委托的权限,登录将继续,并且已授予给该用户的所有 Microsoft Graph 委托的权限都将包含在访问令牌中。 如果没有为请求的资源(本例中为 Microsoft Graph)授予任何权限,则会为该应用程序上为列表中的所有 API 配置的所有必需权限显示同意提示。
示例 1:用户或租户管理员已授予权限
在此示例中,用户或租户管理员向客户端授予了 Mail.Read
和 User.Read
Microsoft Graph 权限。
如果客户端请求 scope=https://graph.microsoft.com/.default
,则不会显示任何同意提示,不管客户端应用程序已为 Microsoft Graph 注册的权限的内容如何。 返回的令牌包含范围 Mail.Read
和 User.Read
。
示例 2:用户在客户端和资源之间未授予权限
在此示例中,用户尚未在客户端和 Microsoft Graph 之间授予同意,也没有管理员。 客户端已针对权限 User.Read
和 Contacts.Read
进行注册。 它还针对 Azure Key Vault 范围 https://vault.azure.net/user_impersonation
进行了注册。
当客户端请求用于 scope=https://graph.microsoft.com/.default
的令牌时,用户会看到针对 Microsoft Graph User.Read
范围、Contacts.Read
范围和 Azure Key Vault user_impersonation
范围的同意页面。 返回的令牌仅包含 User.Read
范围和 Contacts.Read
范围,并且只能用于 Microsoft Graph。
示例 3:用户已同意,客户端请求更多范围
在此示例中,用户已为客户端许可 Mail.Read
。 客户端已针对 Contacts.Read
范围进行注册。
客户端首先使用 scope=https://graph.microsoft.com/.default
登录。 基于响应的 scopes
参数,应用程序的代码检测到仅授予了 Mail.Read
。 然后,客户端使用 scope=https://graph.microsoft.com/.default
再次登录,这一次使用 prompt=consent
强制同意。 如果允许用户同意应用程序注册的所有权限,则会显示同意提示。 (如果不允许,则将显示一条错误消息或管理员同意请求窗体。)Contacts.Read
和 Mail.Read
都会在同意提示中出现。 如果授予同意并且登录继续,则返回的令牌用于 Microsoft Graph,并包含 Mail.Read
和 Contacts.Read
。
将 .default
范围与客户端配合使用
在某些情况下,客户端可以请求其自己的 .default
范围。 以下示例演示了这种情况。
// Line breaks are for legibility only.
GET https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize
?response_type=token //Code or a hybrid flow is also possible here
&client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=9ada6f8a-6d83-41bc-b169-a306c21527a5/.default
&redirect_uri=https%3A%2F%2Flocalhost
&state=1234
此代码示例为所有已注册的权限生成同意页,前提是前面有关同意和 .default
的说明适用于此方案。 然后,此代码返回 id_token
,而不是访问令牌。
此设置不应由面向 Microsoft 标识平台的新客户端使用。 请务必从 Azure AD 身份验证库 (ADSL) 迁移到 Microsoft 身份验证库 (MSAL)。
客户端凭据授权流和 .default
.default
的另一种用法是在非交互式应用程序(例如,使用客户端凭据授权流来调用 Web API 的守护程序应用)中请求应用角色(也称为应用程序权限)。
若要为 Web API 定义应用角色(应用程序权限),请参阅在应用程序中添加应用角色。
客户端服务中的客户端凭据请求必须包含 scope={resource}/.default
。 此处,{resource}
是你的应用要调用的 Web API,你希望为该 API 获取访问令牌。 不支持使用单个应用程序权限(角色)发出客户端凭据请求。 为该 Web API 授予的所有应用角色(应用程序权限)都包含在返回的访问令牌中。
若要授予对所定义的应用角色的访问权限,包括为应用程序授予管理员同意,请参阅配置客户端应用程序以访问 Web API。
尾随斜杠和 .default
某些资源 URI 包含尾随正斜杠,例如 https://contoso.com/
(不是 https://contoso.com
)。 尾随斜杠可能导致令牌验证出现问题。 问题主要发生在为 Azure 资源管理器 (https://management.azure.com/
) 请求令牌时。
在这种情况下,资源 URI 上的尾随斜杠意味着请求令牌时必须存在此斜杠。 因此,在请求 https://management.azure.com/
的令牌并使用 .default
时,必须请求 https://management.azure.com//.default
(注意双斜杠!)。
一般情况下,如果你确认令牌被颁发,但 API 在应该接受令牌的情况下拒绝了它,请考虑添加另一个正斜杠并重试。