获取令牌以使用守护程序应用程序调用 Web API

为机密客户端应用获取令牌

在不使用用户交互的情况下运行的守护程序应用程序和其他机密客户端应用使用 OAuth 2.0 客户端凭据流来获取仅限应用的访问令牌。 本文介绍如何配置所需的范围、调用 AcquireTokenForClient API(或其平台等效项)来获取令牌,以及排查常见错误。 在继续操作之前,请确保已创建机密客户端应用程序。

请求的作用域

客户端凭据流请求中的作用域是资源名称,后跟 /.default/.default 表示法告知 Microsoft Entra ID 使用在应用程序注册期间静态声明的应用程序级权限。 另外,这些 API 权限必须由租户管理员授予。

下面是将 Web API 的范围定义为 appsettings.json 文件中的部分配置的示例。 此示例摘自 GitHub 上的 .NET 控制台守护程序代码示例。

{
    "AzureAd": {
        // Same AzureAd section as before.
    },

    "MyWebApi": {
        "BaseUrl": "https://localhost:44372/",
        "RelativePath": "api/TodoList",
        "RequestAppToken": true,
        "Scopes": [ "[Enter here the scopes for your web API]" ]
    }
}

Azure AD (v1.0) 资源

客户端凭据使用的作用域应始终为资源 ID,后接 /.default

重要

当 MSAL 为接受 1.0 版本访问令牌的资源请求访问令牌时,Microsoft Entra ID 会通过提取所请求范围中最后一个斜杠之前的所有内容,并将其用作资源标识符,来解析所需的受众。 因此,就像 Azure SQL 数据库 (https://database.chinacloudapi.cn) 一样,如果资源需要以斜杠结尾的受众(对于 Azure SQL 数据库为 https://database.chinacloudapi.cn/),你将需要请求范围 https://database.chinacloudapi.cn//.default。 (注意双斜杠。)另请参阅 MSAL.NET 问题 #747:Resource url's trailing slash is omitted, which caused sql auth failure

AcquireTokenForClient API

为了获取应用的令牌,请使用 AcquireTokenForClient 或其等效命令,具体取决于平台。

使用 Microsoft。Identity.Web 不需要直接获取令牌。 可以使用更高级别的 API,如从守护程序应用程序调用一个 Web API中所示。 但如果使用的是需要令牌的 SDK,则可以通过抽象获取应用令牌 ITokenAcquirer ,如以下示例所示:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;

// In the Program.cs, acquire a token for your downstream API

var tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
ITokenAcquirer acquirer = tokenAcquirerFactory.GetTokenAcquirer();
AcquireTokenResult tokenResult = await acquirer.GetTokenForUserAsync(new[] { "https://microsoftgraph.chinacloudapi.cn/.default" });
string accessToken = tokenResult.AccessToken;

协议

如果还没有适用于所选语言的库,你可能希望直接使用协议:

第一种情况:使用共享机密访问令牌请求

POST /{tenant}/oauth2/v2.0/token HTTP/1.1           //Line breaks for clarity.
Host: login.partner.microsoftonline.cn
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2F.default
&client_secret=A1b-C2d_E3f.H4i,J5k?L6m!N7o-P8q_R9s.T0u
&grant_type=client_credentials

第二种情况:使用证书访问令牌请求

POST /{tenant}/oauth2/v2.0/token HTTP/1.1               // Line breaks for clarity.
Host: login.partner.microsoftonline.cn
Content-Type: application/x-www-form-urlencoded

scope=https%3A%2F%2Fmicrosoftgraph.chinacloudapi.cn%2F.default
&client_id=11112222-bbbb-3333-cccc-4444dddd5555
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=aaaaaaaa-0b0b-...
&grant_type=client_credentials

有关详细信息,请参阅协议文档:Microsoft 标识平台和 OAuth 2.0 客户端凭据流

故障排除

你是否使用过 resource/.default 作用域?

如果出现一条错误消息,指出所使用的作用域无效,则表明你并未使用 resource/.default 作用域。

如果在调用 API 时出现错误“权限不足,无法完成该操作”, 则租户管理员需要授予对应用程序的权限。

如果未向应用程序授予管理员同意,API 将返回类似于以下示例的错误响应:

Failed to call the web API: Forbidden
Content: {
  "error": {
    "code": "Authorization_RequestDenied",
    "message": "Insufficient privileges to complete the operation.",
    "innerError": {
      "request-id": "<guid>",
      "date": "<date>"
    }
  }
}

根据角色选择以下选项之一。

云应用程序管理员

对于云应用程序管理员,请转到 Microsoft Entra 管理中心中的“企业应用程序”。 选择应用注册,然后从左侧窗格的“安全”部分中选择“权限”。 然后,选择标有 为 {Tenant Name} 授予管理员同意 的大按钮(其中 {Tenant Name} 是目录的名称)。

标准用户

对于租户的标准用户,可以请求云应用程序管理员为应用程序授予管理员同意。 若要请求同意,请将管理员定向到以下管理员同意终结点 URL:

https://login.partner.microsoftonline.cn/Enter_the_Tenant_Id_Here/adminconsent?client_id=Enter_the_Application_Id_Here

在 URL 中:

  • Enter_the_Tenant_Id_Here 替换为租户 ID 或租户名称(例如,contoso.microsoft.com)。
  • Enter_the_Application_Id_Here 是已注册的应用程序的应用程序(客户端)ID。

在使用上述 URL 为应用授予同意后,可能会显示错误 AADSTS50011: No reply address is registered for the application。 发生 AADSTS50011 此错误的原因是应用程序和 URL 没有重定向 URI。 可以放心地忽略此错误。

是否在调用自己的 API?

如果你的守护程序应用调用你自己的 Web API,并且你无法向守护程序的应用注册添加应用权限,则需要将应用角色添加到 Web API 的应用注册

后续步骤

转到此方案中的下一篇文章:调用 Web API