警告
本内容适用于较旧版本的 Azure AD v1.0 终结点。 将 Microsoft标识平台 用于新项目。
注释
如果未告知服务器计划调用的资源,则服务器不会触发该资源的条件访问策略。 因此,若要触发 MFA,需要在 URL 中包含资源。
Azure Active Directory (Azure AD) 使用 OAuth 2.0 来授权访问 Azure AD 租户中的 Web 应用程序和 Web API。 本指南与语言无关,介绍如何在不使用任何 开源库的情况下发送和接收 HTTP 消息。
OAuth 2.0 授权代码流在 OAuth 2.0 规范的第 4.1 节中介绍。 它用于在大多数应用程序类型(包括 Web 应用和本机安装的应用)中执行身份验证和授权。
将应用程序注册到您的 AD 租户
首先,将应用程序注册到 Azure Active Directory (Azure AD) 租户。 这将为你的应用程序提供一个应用程序 ID,并使它能够接收令牌。
登录到 Azure 门户。
选择 Azure AD 租户,方法是在页面右上角选择帐户,然后选择 “切换目录 ”导航,然后选择相应的租户。
- 如果帐户下只有一个 Azure AD 租户,或者已选择相应的 Azure AD 租户,请跳过此步骤。
在 Azure 门户中,搜索并选择 Azure Active Directory。
在 Azure Active Directory 左侧菜单中,选择 “应用注册”,然后选择“ 新建注册”。
按照提示进行操作并创建新应用程序。 本教程的 Web 应用程序或公共客户端(移动和桌面)应用程序并不重要,但如果想要 Web 应用程序或公共客户端应用程序的特定示例,请查看 我们的快速入门。
- 名称 是应用程序名称,并向最终用户描述应用程序。
- 在“支持的帐户类型”下,选择“任何组织目录中的帐户和个人 Microsoft 帐户”。
- 提供 重定向 URI。 对于 Web 应用程序,这是用户可以登录的应用的基本 URL。 例如,
http://localhost:12345
。 对于公共客户端(移动 & 桌面),Azure AD 使用它返回令牌响应。 输入特定于应用程序的值。 例如,http://MyFirstAADApp
。
完成注册后,Azure AD 将为应用程序分配唯一的客户端标识符( 应用程序 ID)。 在下一部分中需要此值,因此请从应用程序页复制此值。
若要在 Azure 门户中查找应用程序,请选择 “应用注册”,然后选择“ 查看所有应用程序”。
OAuth 2.0 授权流
概括而言,应用程序的整个授权流如下所示:
请求授权代码
授权代码流始于客户端将用户定向到 /authorize
终结点。 在此请求中,客户端指示需要从用户获取的权限。 可以通过在 Azure 门户中选择 应用注册 > 终结点 来获取租户的 OAuth 2.0 授权终结点。
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/authorize?
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%3A12345
&response_mode=query
&resource=https%3A%2F%2Fservice.contoso.com%2F
&state=12345
参数 | 类型 | DESCRIPTION |
---|---|---|
租户 | 必填 | 请求路径中的 {tenant} 值可用于控制登录应用程序的用户。 允许的值是租户标识符,例如,用于租户无关令牌的 8eaef023-2b34-4da1-9baa-8bc8c9d6a490 、contoso.onmicrosoft.com 或 common 。 |
客户编号 | 必填 | 您在注册应用程序到 Azure AD 时所分配的应用程序 ID。 可以在 Azure 门户中找到此信息。 在服务边栏中单击 Azure Active Directory ,单击 “应用注册”,然后选择该应用程序。 |
response_type(响应类型) | 必填 | 必须包括授权代码流的 code 。 |
重定向URI | 推荐 | 应用的 redirect_uri,你的应用可在其中发送和接收身份验证响应。 它必须与您在门户中注册的某个 redirect_uris 完全匹配,但 URL 必须进行编码。 对于本机应用和移动应用,应使用默认值 https://login.microsoftonline.com/common/oauth2/nativeclient 。 |
响应模式 | 可选 | 指定应该用于将生成的令牌发送回应用的方法。 可以是 query 、fragment 或 form_post 。
query 提供代码作为重定向 URI 上的查询字符串参数。 如果要使用隐式流请求 ID 令牌,则不能按 OpenID 规范中指定的方式使用query 。如果只是请求代码,则可以使用query 、fragment 或form_post 。
form_post 对重定向 URI 执行包含代码的 POST。 默认情况下,代码流程的默认值为 query 。 |
州 | 推荐 | 请求中包含的一个值,也在令牌响应中返回。 随机生成的唯一值通常用于 防止跨站点请求伪造攻击。 该状态也用于在身份验证请求出现之前,对应用中用户的状态信息进行编码,例如用户之前浏览的网页或视图。 |
资源 | 推荐 | 目标 Web API 的应用 ID URI(受保护的资源)。 若要查找应用 ID URI,请在 Azure 门户中单击 “Azure Active Directory”,单击 “应用程序注册”,打开应用程序的 “设置” 页,然后单击“ 属性”。 它也可能是外部资源,例如 https://graph.microsoft.com 。 这在授权或令牌请求之一中是必需的。 为了减少身份验证提示的次数,可以将其包含在授权请求中,以确保获取用户的同意。 |
范围 | 忽视 | 对于 v1 Azure AD 应用程序,必须在 Azure 门户中的“设置 |
提示 | 可选 | 指示所需的用户交互类型。 有效值是: 登录:应提示用户重新进行身份验证。 select_account:系统会提示用户选择帐户,从而中断单一登录。 用户可以选择现有的已登录帐户,输入其已记住帐户的凭据,或选择完全使用不同的帐户。 同意:已授予用户同意,但需要更新。 应提示用户同意。 admin_consent:应提示管理员代表组织中的所有用户同意 |
登录提示 | 可选 | 如果事先知道用户名,可用于预先填充用户登录页的用户名/电子邮件地址字段。 通常,应用在重新身份验证期间使用此参数,并且已使用 preferred_username 声明从以前的登录中提取用户名。 |
domain_hint | 可选 | 提供关于用户应使用哪个租户或域进行登录的提示。 domain_hint的值是租户的已注册域。 如果租户已联合到本地目录,AAD 会重定向到指定的租户联合服务器。 |
代码挑战方法 | 推荐 | 用于为 code_verifier 参数编码 code_challenge 的方法。 可以是 plain 或 S256 之一。 如果已排除在外,且包含了 code_challenge ,则假定 code_challenge 为纯文本。 Azure AAD v1.0 同时支持 plain 和 S256 。 有关详细信息,请参阅 PKCE RFC。 |
代码挑战 | 推荐 | 通过本机或公共客户端使用证明密钥交换(PKCE)来保护授权代码许可。 如果包含 code_challenge_method ,则需要。 有关详细信息,请参阅 PKCE RFC。 |
注释
如果用户是组织的一部分,则组织的管理员可以代表用户同意或拒绝用户,或者允许用户同意。 仅当管理员允许时,用户才获得许可的选项。
此时,系统会要求用户输入其凭据并同意应用在 Azure 门户中请求的权限。 用户进行身份验证并授予同意后,Azure AD 会将响应发送到请求中地址 redirect_uri
,并附带代码。
成功的响应
成功的响应可能如下所示:
GET HTTP/1.1 302 Found
Location: http://localhost:12345/?code= AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrqqf_ZT_p5uEAEJJ_nZ3UmphWygRNy2C3jJ239gV_DBnZ2syeg95Ki-374WHUP-i3yIhv5i-7KU2CEoPXwURQp6IVYMw-DjAOzn7C3JCu5wpngXmbZKtJdWmiBzHpcO2aICJPu1KvJrDLDP20chJBXzVYJtkfjviLNNW7l7Y3ydcHDsBRKZc3GuMQanmcghXPyoDg41g8XbwPudVh7uCmUponBQpIhbuffFP_tbV8SNzsPoFz9CLpBCZagJVXeqWoYMPe2dSsPiLO9Alf_YIe5zpi-zY4C3aLw5g9at35eZTfNd0gBRpR5ojkMIcZZ6IgAA&session_state=7B29111D-C220-4263-99AB-6F6E135D75EF&state=D79E5777-702E-4260-9A62-37F75FF22CCE
参数 | DESCRIPTION |
---|---|
管理员同意 | 如果管理员同意请求提示,则值为 True。 |
代码 | 应用程序请求的授权代码。 应用程序可以使用授权代码为目标资源请求访问令牌。 |
会话状态 | 标识当前用户会话的唯一值。 此值是一个 GUID,但应被视为不透明的值,无需检查即可通过该值。 |
州 | 如果请求中包含 state 参数,响应中就应该出现相同的值。 应用程序在使用响应之前验证请求和响应中的状态值是否相同是一种好的做法。 这有助于检测针对客户端的 跨站点请求伪造(CSRF)攻击 。 |
错误响应
错误响应也可以发送到 redirect_uri
,以便应用程序可以适当地处理它们。
GET http://localhost:12345/?
error=access_denied
&error_description=the+user+canceled+the+authentication
参数 | DESCRIPTION |
---|---|
错误 | OAuth 2.0 授权框架的第 5.2 节中定义的错误代码值。 下表描述了 Azure AD 返回的错误代码。 |
错误描述 | 更加详细的错误说明。 此消息并非针对最终用户而设计。 |
州 | 状态值是随机生成的非重用值,在请求中发送并在响应中返回,以防止跨站点请求伪造(CSRF)攻击。 |
授权终结点错误的错误代码
下表描述了可在错误响应的 error
参数中返回的各个错误代码。
错误代码 | DESCRIPTION | 客户行动 |
---|---|---|
无效请求 | 协议错误,例如,缺少必需的参数。 | 修复并重新提交请求。 这是一个开发错误,通常在初步测试时发现。 |
未授权的客户端 | 不允许客户端应用程序请求授权代码。 | 当客户端应用程序未在 Azure AD 中注册或未添加到用户的 Azure AD 租户时,通常会发生这种情况。 应用程序可以通过提供安装说明来提示用户进行应用程序的安装,并将其添加到 Azure AD。 |
访问被拒绝 | 资源所有者拒绝了许可 | 除非用户同意,否则客户端应用程序可以通知用户无法继续。 |
不支持的响应类型 | 授权服务器不支持请求中的响应类型。 | 修复并重新提交请求。 这是一个开发错误,通常在初步测试时发现。 |
服务器错误 | 服务器遇到意外的错误。 | 重试请求。 这些错误可能是临时状况导致的。 客户端应用程序可能会向用户解释其响应因临时错误而延迟。 |
暂时不可用 | 服务器暂时繁忙,无法处理请求。 | 重试请求。 客户端应用程序可能会向用户解释,其响应因临时条件而延迟。 |
资源无效 | 目标资源无效,因为它不存在,Azure AD 找不到它,或者未正确配置。 | 这表示资源(如果存在)尚未在租户中配置。 应用程序可以通过提供安装说明来提示用户进行应用程序的安装,并将其添加到 Azure AD。 |
使用授权代码请求访问令牌
现在,你已经获取了授权代码,并且用户已授予权限,你可以通过发送 POST 请求到 /token
终结点,将该代码兑换为所需资源的访问令牌。
// Line breaks for legibility only
POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=2d4d11a2-f814-46a7-890a-274a72a7309e
&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrqqf_ZT_p5uEAEJJ_nZ3UmphWygRNy2C3jJ239gV_DBnZ2syeg95Ki-374WHUP-i3yIhv5i-7KU2CEoPXwURQp6IVYMw-DjAOzn7C3JCu5wpngXmbZKtJdWmiBzHpcO2aICJPu1KvJrDLDP20chJBXzVYJtkfjviLNNW7l7Y3ydcHDsBRKZc3GuMQanmcghXPyoDg41g8XbwPudVh7uCmUponBQpIhbuffFP_tbV8SNzsPoFz9CLpBCZagJVXeqWoYMPe2dSsPiLO9Alf_YIe5zpi-zY4C3aLw5g9at35eZTfNd0gBRpR5ojkMIcZZ6IgAA
&redirect_uri=https%3A%2F%2Flocalhost%3A12345
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=p@ssw0rd
//NOTE: client_secret only required for web apps
参数 | 类型 | DESCRIPTION |
---|---|---|
租户 | 必填 | 请求路径中的 {tenant} 值可用于控制登录应用程序的用户。 允许的值是租户标识符,例如,用于租户无关令牌的 8eaef023-2b34-4da1-9baa-8bc8c9d6a490 、contoso.onmicrosoft.com 或 common 。 |
客户编号 | 必填 | 在您将应用注册到 Azure AD 时分配的应用程序 ID。 可以在 Azure 门户中找到此信息。 应用程序 ID 显示在应用注册的设置中。 |
授权类型 (grant_type) | 必填 | 必须是授权代码流的 authorization_code 。 |
代码 | 必填 | 在上一部分中你获取的authorization_code |
redirect_uri | 必填 |
redirect_uri 注册在客户端应用程序上。 |
客户端密钥 | Web 应用所必需的,不允许用于公共客户端 | 您在 Azure 门户中于 密钥 下为应用程序创建的应用程序机密。 它不能用于本机应用(公共客户端),因为client_secrets无法可靠地存储在设备上。 Web 应用程序和 Web API 接口(所有机密客户端)需要具备这种能力:能够将 client_secret 安全地存储在服务器端。 client_secret应在发送前进行 URL 编码。 |
资源 | 推荐 | 目标 Web API 的应用 ID URI(受保护的资源)。 若要查找应用 ID URI,请在 Azure 门户中单击 “Azure Active Directory”,单击 “应用程序注册”,打开应用程序的 “设置” 页,然后单击“ 属性”。 它也可能是外部资源,例如 https://graph.microsoft.com 。 这在授权或令牌请求之一中是必需的。 为了减少身份验证提示,可以将其放入授权请求中,以确保获得用户的同意。 如果同时在授权请求和令牌请求中,则资源的参数必须匹配。 |
代码验证器 | 可选 | 用于获取授权代码的同一code_verifier。 如果授权码授权请求中使用了PKCE,则为必需。 有关详细信息,请参阅 PKCE RFC |
若要查找应用 ID URI,请在 Azure 门户中单击 “Azure Active Directory”,单击 “应用程序注册”,打开应用程序的 “设置” 页,然后单击“ 属性”。
成功的响应
成功响应后,Azure AD 将返回 访问令牌 。 为了最大程度地减少来自客户端应用程序的网络调用及其关联的延迟,客户端应用程序应在 OAuth 2.0 响应中指定的令牌生存期内缓存访问令牌。 若要确定令牌生存期,请使用 expires_in
或 expires_on
参数值。
如果 Web API 资源返回 invalid_token
错误代码,这可能表示资源已确定令牌已过期。 如果客户端和资源时钟时间不同(称为“时间倾斜”),则资源可能会认为令牌在从客户端缓存中清除令牌之前过期。 如果发生这种情况,请从缓存中清除令牌,即使它仍在其计算生存期内也是如此。
成功的响应可能如下所示:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiJodHRwczovL3NlcnZpY2UuY29udG9zby5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvN2ZlODE0NDctZGE1Ny00Mzg1LWJlY2ItNmRlNTdmMjE0NzdlLyIsImlhdCI6MTM4ODQ0MDg2MywibmJmIjoxMzg4NDQwODYzLCJleHAiOjEzODg0NDQ3NjMsInZlciI6IjEuMCIsInRpZCI6IjdmZTgxNDQ3LWRhNTctNDM4NS1iZWNiLTZkZTU3ZjIxNDc3ZSIsIm9pZCI6IjY4Mzg5YWUyLTYyZmEtNGIxOC05MWZlLTUzZGQxMDlkNzRmNSIsInVwbiI6ImZyYW5rbUBjb250b3NvLmNvbSIsInVuaXF1ZV9uYW1lIjoiZnJhbmttQGNvbnRvc28uY29tIiwic3ViIjoiZGVOcUlqOUlPRTlQV0pXYkhzZnRYdDJFYWJQVmwwQ2o4UUFtZWZSTFY5OCIsImZhbWlseV9uYW1lIjoiTWlsbGVyIiwiZ2l2ZW5fbmFtZSI6IkZyYW5rIiwiYXBwaWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctODkwYS0yNzRhNzJhNzMwOWUiLCJhcHBpZGFjciI6IjAiLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJhY3IiOiIxIn0.JZw8jC0gptZxVC-7l5sFkdnJgP3_tRjeQEPgUn28XctVe3QqmheLZw7QVZDPCyGycDWBaqy7FLpSekET_BftDkewRhyHk9FW_KeEz0ch2c3i08NGNDbr6XYGVayNuSesYk5Aw_p3ICRlUV1bqEwk-Jkzs9EEkQg4hbefqJS6yS1HoV_2EsEhpd_wCQpxK89WPs3hLYZETRJtG5kvCCEOvSHXmDE6eTHGTnEgsIk--UlPe275Dvou4gEAwLofhLDQbMSjnlV5VLsjimNBVcSRFShoxmQwBJR_b2011Y5IuD6St5zPnzruBbZYkGNurQK63TJPWmRd3mbJsGM0mf3CUQ",
"token_type": "Bearer",
"expires_in": "3600",
"expires_on": "1388444763",
"resource": "https://service.contoso.com/",
"refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4rTfgV29ghDOHRc2B-C_hHeJaJICqjZ3mY2b_YNqmf9SoAylD1PycGCB90xzZeEDg6oBzOIPfYsbDWNf621pKo2Q3GGTHYlmNfwoc-OlrxK69hkha2CF12azM_NYhgO668yfcUl4VBbiSHZyd1NVZG5QTIOcbObu3qnLutbpadZGAxqjIbMkQ2bQS09fTrjMBtDE3D6kSMIodpCecoANon9b0LATkpitimVCrl-NyfN3oyG4ZCWu18M9-vEou4Sq-1oMDzExgAf61noxzkNiaTecM-Ve5cq6wHqYQjfV9DOz4lbceuYCAA",
"scope": "https%3A%2F%2Fgraph.microsoft.com%2Fmail.read",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctODkwYS0yNzRhNzJhNzMwOWUiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83ZmU4MTQ0Ny1kYTU3LTQzODUtYmVjYi02ZGU1N2YyMTQ3N2UvIiwiaWF0IjoxMzg4NDQwODYzLCJuYmYiOjEzODg0NDA4NjMsImV4cCI6MTM4ODQ0NDc2MywidmVyIjoiMS4wIiwidGlkIjoiN2ZlODE0NDctZGE1Ny00Mzg1LWJlY2ItNmRlNTdmMjE0NzdlIiwib2lkIjoiNjgzODlhZTItNjJmYS00YjE4LTkxZmUtNTNkZDEwOWQ3NGY1IiwidXBuIjoiZnJhbmttQGNvbnRvc28uY29tIiwidW5pcXVlX25hbWUiOiJmcmFua21AY29udG9zby5jb20iLCJzdWIiOiJKV3ZZZENXUGhobHBTMVpzZjd5WVV4U2hVd3RVbTV5elBtd18talgzZkhZIiwiZmFtaWx5X25hbWUiOiJNaWxsZXIiLCJnaXZlbl9uYW1lIjoiRnJhbmsifQ."
}
参数 | DESCRIPTION |
---|---|
访问令牌 (access_token) | 请求的访问令牌。 这是一个不透明的字符串 - 它取决于资源预期接收的内容,并不适合客户端查看。 应用可以使用此令牌对受保护的资源(如 Web API)进行身份验证。 |
令牌类型 | 指示标记类型值。 Azure AD 支持的唯一类型是 Bearer。 有关持有者令牌的详细信息,请参阅 OAuth2.0 授权框架:持有者令牌用法(RFC 6750) |
有效期 | 访问令牌的有效期是多久(以秒为单位)。 |
到期日期 | 访问令牌过期的时间。 日期表示为从 1970-01-01T0:0:0Z UTC 到过期时间的秒数。 此值用于确定缓存令牌的生存期。 |
资源 | Web API 的应用 ID URI(受保护的资源)。 |
范围 | 向客户端应用程序授予的模拟权限。 默认权限为 user_impersonation . 安全资源的所有者可以在 Azure AD 中注册其他值。 |
刷新令牌 | OAuth 2.0 刷新令牌。 在当前访问令牌过期后,应用可以使用此令牌获取其他访问令牌。 刷新令牌的生存期很长,而且可以用于延长保留资源访问权限的时间。 |
身份令牌 | 表示 ID 令牌的未签名 JSON Web 令牌(JWT)。 应用可以通过对该令牌的段进行 base64Url 解码,以请求有关登录用户的信息。 应用可以缓存值并显示这些值,但不应依赖它们进行任何授权或安全边界。 |
有关 JSON Web 令牌的详细信息,请参阅 JWT IETF 草稿规范。 若要了解关于id_tokens
的详细信息,请参阅v1.0 OpenID Connect 流。
错误响应
令牌颁发终结点错误是 HTTP 错误代码,因为客户端直接调用令牌颁发终结点。 除了 HTTP 状态代码,Azure AD 令牌颁发终结点还返回一个 JSON 文档,其中包含描述错误的对象。
示例错误响应可能如下所示:
{
"error": "invalid_grant",
"error_description": "AADSTS70002: Error validating credentials. AADSTS70008: The provided authorization code or refresh token is expired. Send a new interactive authorization request for this user and resource.\r\nTrace ID: 3939d04c-d7ba-42bf-9cb7-1e5854cdce9e\r\nCorrelation ID: a8125194-2dc8-4078-90ba-7b6592a7f231\r\nTimestamp: 2016-04-11 18:00:12Z",
"error_codes": [
70002,
70008
],
"timestamp": "2016-04-11 18:00:12Z",
"trace_id": "3939d04c-d7ba-42bf-9cb7-1e5854cdce9e",
"correlation_id": "a8125194-2dc8-4078-90ba-7b6592a7f231"
}
参数 | DESCRIPTION |
---|---|
错误 | 可用于分类错误类型并响应错误的错误码字符串。 |
错误描述 | 帮助开发人员识别身份验证错误根本原因的特定错误消息。 |
错误代码 | 可帮助诊断的 STS 特定错误代码列表。 |
时间戳 | 发生错误的时间。 |
追踪ID | 可帮助诊断的请求唯一标识符。 |
关联标识符 (correlation_id) | 可帮助跨组件诊断的请求唯一标识符。 |
HTTP 状态代码
下表列出了令牌颁发终结点返回的 HTTP 状态代码。 在某些情况下,错误代码足以描述响应,但如果存在错误,则需要分析随附的 JSON 文档并检查其错误代码。
HTTP 代码 | DESCRIPTION |
---|---|
400 | 默认 HTTP 代码。 在大多数情况下使用,通常是由于请求格式不正确。 修复并重新提交请求。 |
401 | 身份验证失败。 例如,请求缺少client_secret参数。 |
403 | 授权失败。 例如,用户无权访问资源。 |
500 | 服务中发生了内部错误。 重试请求。 |
令牌终结点错误的错误代码
错误代码 | DESCRIPTION | 客户行动 |
---|---|---|
无效请求 | 协议错误,例如,缺少必需的参数。 | 修复并重新提交请求 |
无效的授权 | 授权代码无效或已过期。 | 尝试向 /authorize 终结点发送新请求 |
未授权的客户端 | 经过身份验证的客户端无权使用此授权授权类型。 | 当客户端应用程序未在 Azure AD 中注册或未添加到用户的 Azure AD 租户时,通常会发生这种情况。 应用程序可以通过提供安装说明来提示用户进行应用程序的安装,并将其添加到 Azure AD。 |
无效客户端 | 客户端身份验证失败。 | 客户端凭据无效。 若要修复,应用程序管理员应更新凭据。 |
不支持的授权类型 | 授权服务器不支持授权授权类型。 | 更改请求中的授权类型。 这种类型的错误应该只在开发过程中发生,并且应该在初始测试过程中检测到。 |
资源无效 | 目标资源无效,因为它不存在,Azure AD 找不到它,或者未正确配置。 | 这表示资源(如果存在)尚未在租户中配置。 应用程序可以通过提供安装说明来提示用户进行应用程序的安装,并将其添加到 Azure AD。 |
需要交互 | 请求需要用户交互。 例如,需要其他身份验证步骤。 | 而是使用同一资源的交互式授权请求重试,而不是非交互式请求。 |
暂时不可用 | 服务器暂时繁忙,无法处理请求。 | 重试请求。 客户端应用程序可能会向用户解释,其响应因临时条件而延迟。 |
使用访问令牌访问资源
成功获取 access_token
之后,可以在请求 Web API 时,通过在 Authorization
标头中包含令牌来使用它。
RFC 6750 规范介绍了如何在 HTTP 请求中使用持有者令牌来访问受保护的资源。
示例请求
GET /data HTTP/1.1
Host: service.contoso.com
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiJodHRwczovL3NlcnZpY2UuY29udG9zby5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvN2ZlODE0NDctZGE1Ny00Mzg1LWJlY2ItNmRlNTdmMjE0NzdlLyIsImlhdCI6MTM4ODQ0MDg2MywibmJmIjoxMzg4NDQwODYzLCJleHAiOjEzODg0NDQ3NjMsInZlciI6IjEuMCIsInRpZCI6IjdmZTgxNDQ3LWRhNTctNDM4NS1iZWNiLTZkZTU3ZjIxNDc3ZSIsIm9pZCI6IjY4Mzg5YWUyLTYyZmEtNGIxOC05MWZlLTUzZGQxMDlkNzRmNSIsInVwbiI6ImZyYW5rbUBjb250b3NvLmNvbSIsInVuaXF1ZV9uYW1lIjoiZnJhbmttQGNvbnRvc28uY29tIiwic3ViIjoiZGVOcUlqOUlPRTlQV0pXYkhzZnRYdDJFYWJQVmwwQ2o4UUFtZWZSTFY5OCIsImZhbWlseV9uYW1lIjoiTWlsbGVyIiwiZ2l2ZW5fbmFtZSI6IkZyYW5rIiwiYXBwaWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctODkwYS0yNzRhNzJhNzMwOWUiLCJhcHBpZGFjciI6IjAiLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJhY3IiOiIxIn0.JZw8jC0gptZxVC-7l5sFkdnJgP3_tRjeQEPgUn28XctVe3QqmheLZw7QVZDPCyGycDWBaqy7FLpSekET_BftDkewRhyHk9FW_KeEz0ch2c3i08NGNDbr6XYGVayNuSesYk5Aw_p3ICRlUV1bqEwk-Jkzs9EEkQg4hbefqJS6yS1HoV_2EsEhpd_wCQpxK89WPs3hLYZETRJtG5kvCCEOvSHXmDE6eTHGTnEgsIk--UlPe275Dvou4gEAwLofhLDQbMSjnlV5VLsjimNBVcSRFShoxmQwBJR_b2011Y5IuD6St5zPnzruBbZYkGNurQK63TJPWmRd3mbJsGM0mf3CUQ
错误响应
实现 RFC 6750 的安全资源发出 HTTP 状态代码。 如果请求不包含身份验证凭据或缺少令牌,则响应将包含标头 WWW-Authenticate
。 当请求失败时,资源服务器会响应 HTTP 状态代码和错误代码。
下面是客户端请求不包含持有者令牌时失败响应的示例:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer authorization_uri="https://login.microsoftonline.com/contoso.com/oauth2/authorize", error="invalid_token", error_description="The access token is missing.",
错误参数
参数 | DESCRIPTION |
---|---|
授权 URI | 授权服务器的 URI(物理终结点)。 此值还用作查找键,用于从发现终结点获取有关服务器的详细信息。 客户端必须验证授权服务器是否受信任。 当资源受 Azure AD 保护时,足以验证 URL 是否以 |
错误 | OAuth 2.0 授权框架的第 5.2 节中定义的错误代码值。 |
错误描述 | 错误的更详细描述。 此消息不适合设计为最终用户友好。 |
资源-ID | 返回资源的唯一标识符。 当客户端应用程序请求资源的令牌时,客户端应用程序可以使用此标识符作为参数的值 resource 。 客户端应用程序必须验证此值,否则恶意服务可能会引发 特权提升 攻击 防止攻击的建议策略是验证是否 |
持有者身份验证错误代码
RFC 6750 规范为响应中使用 WWW-Authenticate 标头和持有者方案的资源定义了以下错误。
HTTP 状态代码 | 错误代码 | DESCRIPTION | 客户行动 |
---|---|---|---|
400 | 无效请求 | 请求格式不正确。 例如,它可能缺少参数或使用同一参数两次。 | 修复错误并重试请求。 此类错误应仅在开发期间发生,并在初始测试中检测到。 |
401 | 无效令牌 | 访问令牌缺失、无效或已吊销。 error_description 参数的值提供了更多详细信息。 | 从授权服务器请求新令牌。 如果新令牌失败,则发生了意外错误。 向用户发送错误消息,并在随机延迟后重试。 |
403 | 权限不足 | 访问令牌不包含访问资源所需的模拟权限。 | 将新的授权请求发送到授权终结点。 如果响应包含范围参数,请使用请求中的范围值来访问资源。 |
403 | 访问不足 | 令牌的主题没有访问资源所需的权限。 | 提示用户使用其他帐户或请求对指定资源的权限。 |
刷新访问令牌
访问令牌是生存期较短的,在访问令牌过期后必须刷新才能继续访问资源。 可以通过向/token
终结点提交另一个POST
请求来刷新access_token
,但这次提供refresh_token
而不是code
。 刷新令牌适用于所有客户端已获得访问权限的资源,因此,在请求resource=https://graph.microsoft.com
时颁发的刷新令牌可以用来请求resource=https://contoso.com/api
的新访问令牌。
刷新令牌没有指定的生存期。 通常,刷新令牌的生存期相对较长。 但是,在某些情况下,刷新令牌会过期、被吊销,或缺少执行所需操作的足够权限。 应用程序需要正确预期和处理令牌颁发终结点返回的错误。
收到包含刷新令牌错误的响应时,请放弃当前刷新令牌并请求新的授权代码或访问令牌。 具体而言,在授权码授予流程中使用刷新令牌时,如果收到包含interaction_required
或invalid_grant
错误代码的响应,请放弃刷新令牌并请求新的授权代码。
对 租户专用 终结点的示例请求(还可以使用 通用 终结点)如下所示,通过使用刷新令牌来获取新的访问令牌:
// Line breaks for legibility only
POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&grant_type=refresh_token
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=JqQX2PNo9bpM0uEihUPzyrh // NOTE: Only required for web apps
成功的响应
成功的令牌响应如下所示:
{
"token_type": "Bearer",
"expires_in": "3600",
"expires_on": "1460404526",
"resource": "https://service.contoso.com/",
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiJodHRwczovL3NlcnZpY2UuY29udG9zby5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvN2ZlODE0NDctZGE1Ny00Mzg1LWJlY2ItNmRlNTdmMjE0NzdlLyIsImlhdCI6MTM4ODQ0MDg2MywibmJmIjoxMzg4NDQwODYzLCJleHAiOjEzODg0NDQ3NjMsInZlciI6IjEuMCIsInRpZCI6IjdmZTgxNDQ3LWRhNTctNDM4NS1iZWNiLTZkZTU3ZjIxNDc3ZSIsIm9pZCI6IjY4Mzg5YWUyLTYyZmEtNGIxOC05MWZlLTUzZGQxMDlkNzRmNSIsInVwbiI6ImZyYW5rbUBjb250b3NvLmNvbSIsInVuaXF1ZV9uYW1lIjoiZnJhbmttQGNvbnRvc28uY29tIiwic3ViIjoiZGVOcUlqOUlPRTlQV0pXYkhzZnRYdDJFYWJQVmwwQ2o4UUFtZWZSTFY5OCIsImZhbWlseV9uYW1lIjoiTWlsbGVyIiwiZ2l2ZW5fbmFtZSI6IkZyYW5rIiwiYXBwaWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctODkwYS0yNzRhNzJhNzMwOWUiLCJhcHBpZGFjciI6IjAiLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJhY3IiOiIxIn0.JZw8jC0gptZxVC-7l5sFkdnJgP3_tRjeQEPgUn28XctVe3QqmheLZw7QVZDPCyGycDWBaqy7FLpSekET_BftDkewRhyHk9FW_KeEz0ch2c3i08NGNDbr6XYGVayNuSesYk5Aw_p3ICRlUV1bqEwk-Jkzs9EEkQg4hbefqJS6yS1HoV_2EsEhpd_wCQpxK89WPs3hLYZETRJtG5kvCCEOvSHXmDE6eTHGTnEgsIk--UlPe275Dvou4gEAwLofhLDQbMSjnlV5VLsjimNBVcSRFShoxmQwBJR_b2011Y5IuD6St5zPnzruBbZYkGNurQK63TJPWmRd3mbJsGM0mf3CUQ",
"refresh_token": "AwABAAAAv YNqmf9SoAylD1PycGCB90xzZeEDg6oBzOIPfYsbDWNf621pKo2Q3GGTHYlmNfwoc-OlrxK69hkha2CF12azM_NYhgO668yfcUl4VBbiSHZyd1NVZG5QTIOcbObu3qnLutbpadZGAxqjIbMkQ2bQS09fTrjMBtDE3D6kSMIodpCecoANon9b0LATkpitimVCrl PM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4rTfgV29ghDOHRc2B-C_hHeJaJICqjZ3mY2b_YNqmf9SoAylD1PycGCB90xzZeEDg6oBzOIPfYsbDWNf621pKo2Q3GGTHYlmNfwoc-OlrxK69hkha2CF12azM_NYhgO668yfmVCrl-NyfN3oyG4ZCWu18M9-vEou4Sq-1oMDzExgAf61noxzkNiaTecM-Ve5cq6wHqYQjfV9DOz4lbceuYCAA"
}
参数 | DESCRIPTION |
---|---|
令牌类型 | 令牌类型。 唯一支持的值是 持有者。 |
有效期 | 令牌的剩余生存期(以秒为单位)。 典型值为 3600(一小时)。 |
到期日期 | 令牌过期的日期和时间。 日期表示为从 1970-01-01T0:0:0Z UTC 到过期时间的秒数。 |
资源 | 标识访问令牌可用于访问的安全资源。 |
范围 | 向本机客户端应用程序授予的模拟权限。 默认权限 为user_impersonation。 目标资源的所有者可以在 Azure AD 中注册备用值。 |
访问令牌 (access_token) | 请求的新访问令牌。 |
刷新令牌 | 新的 OAuth 2.0 刷新令牌,可用于在该响应中的访问令牌过期时请求新的访问令牌。 |
错误响应
示例错误响应可能如下所示:
{
"error": "invalid_resource",
"error_description": "AADSTS50001: The application named https://foo.microsoft.com/mail.read was not found in the tenant named 295e01fc-0c56-4ac3-ac57-5d0ed568f872. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: ef1f89f6-a14f-49de-9868-61bd4072f0a9\r\nCorrelation ID: b6908274-2c58-4e91-aea9-1f6b9c99347c\r\nTimestamp: 2016-04-11 18:59:01Z",
"error_codes": [
50001
],
"timestamp": "2016-04-11 18:59:01Z",
"trace_id": "ef1f89f6-a14f-49de-9868-61bd4072f0a9",
"correlation_id": "b6908274-2c58-4e91-aea9-1f6b9c99347c"
}
参数 | DESCRIPTION |
---|---|
错误 | 可用于分类错误类型并响应错误的错误码字符串。 |
错误描述 | 帮助开发人员识别身份验证错误根本原因的特定错误消息。 |
错误代码 | 可帮助诊断的 STS 特定错误代码列表。 |
时间戳 | 发生错误的时间。 |
跟踪ID | 可帮助诊断的请求唯一标识符。 |
关联标识符 | 可帮助跨组件诊断的请求唯一标识符。 |
有关错误代码的描述和建议的客户端操作,请参阅 令牌终结点错误的错误代码。
后续步骤
若要详细了解 Azure AD v1.0 终结点以及如何向 Web 应用程序和 Web API 添加身份验证和授权,请参阅 示例应用程序。