在 .NET 守护程序应用中调用 API

本指南使用示例 .NET 守护程序应用来演示守护程序应用如何获取令牌来调用受保护的 Web API。 Microsoft Entra 可保护 Web API。

守护程序应用程序可以代表自身(而不是用户)获取一个令牌。 用户无法与守护程序应用程序交互,因为它需要自己的标识。 此类型应用程序通过使用其应用程序标识,并向 Microsoft Entra 外部ID 提供其应用程序 ID、凭据(密码或证书)及应用程序 ID URI 来请求访问令牌。

先决条件

注册守护程序应用程序和 Web API

在此步骤中,你将创建守护程序和 Web API 应用程序注册,并指定 Web API 的范围。

注册 Web API 应用程序

  1. 至少以应用程序开发人员的身份登录到 Microsoft Entra 管理中心

  2. 如果你有权访问多个租户,请使用顶部菜单中的“设置”图标 ,通过“目录 + 订阅”菜单切换到你的外部租户

  3. 浏览到“标识”>“应用程序”>“应用注册”。

  4. 选择“+ 新建注册”。

  5. 在出现的“注册应用程序”页面中,输入应用程序的注册信息:

    1. 在“名称”部分中,输入将向应用用户显示的有意义的应用程序名称,例如“ciam-ToDoList-api”。

    2. 在“支持的帐户类型”下,选择“仅此组织目录中的帐户” 。

  6. 选择“注册”以创建应用程序。

  7. 注册完成后,将显示应用程序的“概述”窗格。 记录要在应用程序源代码中使用的目录(租户)ID 和应用程序(客户端)ID。

配置应用程序角色

API 需要至少为应用程序发布一个应用角色(也称为应用程序权限),以便客户端应用以自己的身份获取访问令牌。 应用程序权限是 API 想要使客户端应用程序能够成功地以自己的身份进行身份验证(无需让用户登录)时应发布的权限类型。 若要发布应用程序权限,请执行下列步骤:

  1. 从“应用注册”页中,选择创建的应用程序(例如 ciam-ToDoList-api)以打开其“概述”页。

  2. 在“管理”下,选择“应用角色”。

  3. 选择“创建应用角色”,输入以下值,然后选择“应用”以保存更改:

    属性
    显示名称 ToDoList.Read.All
    允许的成员类型 应用程序
    ToDoList.Read.All
    说明 允许应用使用“TodoListApi”读写每个用户的待办事项列表
  4. 再次选择“创建应用角色”,为第二个应用角色输入以下值,然后选择“应用”以保存更改:

    属性
    显示名称 ToDoList.ReadWrite.All
    允许的成员类型 应用程序
    ToDoList.ReadWrite.All
    说明 允许应用使用“ToDoListApi”读写每个用户的 ToDo 列表

配置可选声明

可以包含 idtyp 可选声明,以帮助 Web API 确定令牌是应用令牌还是应用 + 用户令牌。 尽管可以将 scp 和 roles 声明的组合用于同一目的,但使用 idtyp 声明仍是区分应用令牌和应用 + 用户令牌的最简单方法。 例如,当令牌为仅限应用的令牌时,此声明的值为 app

注册守护程序应用

若要使应用程序能够让用户通过 Microsoft Entra 登录,必须让 Microsoft Entra 外部 ID 能够感知你创建的应用程序。 应用注册会在应用与 Microsoft Entra 之间建立信任关系。 注册应用程序时,外部 ID 会生成一个称为“应用程序(客户端)ID”的唯一标识符,该值用于在创建身份验证请求时标识应用。

以下步骤演示如何在 Microsoft Entra 管理中心注册应用:

  1. 至少以应用程序开发人员的身份登录到 Microsoft Entra 管理中心

  2. 如果你有权访问多个租户,请使用顶部菜单中的“设置”图标 ,通过“目录 + 订阅”菜单切换到你的外部租户

  3. 浏览到“标识”>“应用程序”>“应用注册”。

  4. 选择“+ 新建注册”。

  5. 在显示的“注册应用程序”页中;

    1. 输入一个向应用用户显示的、有意义的应用程序名称,例如 ciam-client-app
    2. 在“支持的帐户类型”下,选择“仅此组织目录中的帐户” 。
  6. 选择“注册”。

  7. 成功注册后,会显示应用程序的“概述”窗格。 记录要在应用程序源代码中使用的应用程序(客户端)ID

创建客户端机密

为注册的应用创建客户端机密。 应用程序在请求令牌时使用客户端密码来证明其身份。

  1. 从“应用注册”页中,选择创建的应用程序(例如 ciam-client-app)以打开其“概述”页。
  2. 在“管理”下,选择“证书和机密”
  3. 选择“新建客户端机密”。
  4. 在“说明”框中输入对客户端密码的说明(如 ciam 应用客户端密码)。
  5. 在“过期时间”下,选择密码的有效期(根据组织的安全规则),然后选择“添加”。
  6. 记下机密的“值”。 在稍后的步骤中将使用此值进行配置。 离开“证书和机密”后,机密值不会再次显示,并且无法以任何方式检索。 请确保记录它。

向守护程序应用授予 API 权限

  1. 从“应用注册”页中,选择创建的应用程序(例如 ciam-client-app)。

  2. 在“管理”下选择“API 权限” 。

  3. 在“已配置权限”下,选择“添加权限”。

  4. 选择“我的组织使用的 API”选项卡。

  5. 在 API 列表中,选择 API(例如 ciam-ToDoList-api)。

  6. 选择“应用程序权限”选项。 我们选择此选项是因为应用以自身身份登录,而不是以用户身份登录。

  7. 从权限列表中,选择“TodoList.Read.All”、“ToDoList.ReadWrite.All”(必要时使用搜索框)。

  8. 选择“添加权限”按钮。

  9. 此时,你已正确分配了权限。 但是,由于守护程序应用不允许用户与之交互,因此用户本身无法同意这些权限。 若要解决此问题,作为管理员的你必须代表租户中的所有用户同意这些权限:

    1. 选择“为 <租户名称> 授予管理员同意”,然后选择“是”。
    2. 选择“刷新”,然后验证两个权限的“状态”下是否均显示“已为 <租户名称> 授予”。

克隆或下载示例守护程序应用程序和 Web API

若要获取示例应用程序,可以从 GitHub 克隆它或将其下载为 .zip 文件。

  • 若要克隆示例,请打开命令提示符并导航到要创建项目的位置,然后输入以下命令:

    git clone https://github.com/Azure-Samples/ms-identity-ciam-dotnet-tutorial.git
    
  • 下载 .zip 文件。 将其提取到名称长度小于 260 个字符的文件路径。

配置示例守护程序应用和 API

若要在客户端 Web 应用程序示例中使用应用注册,请执行以下操作:

  1. 在代码编辑器中,打开 ms-identity-ciam-dotnet-tutorial/2-Authorization/3-call-own-api-dotnet-core-daemon/ToDoListClient/appsettings.json 文件。

  2. 查找占位符:

    • 查找 Enter_the_Application_Id_Here 并将其替换为你之前注册的守护程序应用的应用程序(客户端)ID。
    • 查找 Enter_the_Tenant_Subdomain_Here 并将其替换为目录(租户)子域。 例如,如果租户主域为 contoso.onmicrosoft.com,请使用 contoso。 如果没有租户名称,请了解如何读取租户详细信息
    • 查找 Enter_the_Client_Secret_Here 并将其替换为你之前复制的守护程序应用机密值。
    • 查找 Enter_the_Web_Api_Application_Id_Here 并将其替换为之前复制的 Web API 的应用程序(客户端)ID。

若要在 Web API 示例中使用应用注册,请执行以下操作:

  1. 在代码编辑器中,打开 ms-identity-ciam-dotnet-tutorial/2-Authorization/3-call-own-api-dotnet-core-daemon/ToDoListAPI/appsettings.json 文件。

  2. 查找占位符:

    • 查找 Enter_the_Application_Id_Here 并将其替换为复制的 Web API 的应用程序(客户端)ID。
    • 查找 Enter_the_Tenant_Id_Here 并将其替换为之前复制的目录(租户)ID。
    • 查找 Enter_the_Tenant_Subdomain_Here 并将其替换为目录(租户)子域。 例如,如果租户主域为 contoso.onmicrosoft.com,请使用 contoso。 如果没有租户名称,请了解如何读取租户详细信息

运行并测试示例守护程序应用和 API

  1. 打开控制台窗口,然后使用以下命令运行 Web API:

    cd 2-Authorization\3-call-own-api-dotnet-core-daemon\ToDoListAPI
    dotnet run
    
  2. 使用以下命令运行守护程序客户端:

    cd 2-Authorization\3-call-own-api-dotnet-core-daemon\ToDoListClient
    dotnet run
    

如果守护程序应用和 Web API 成功运行,则应在控制台窗口中看到类似于以下 JSON 数组的内容:

Posting a to-do...
Retrieving to-do's from server...
To-do data:
ID: 1
User ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee
Message: Bake bread
Posting a second to-do...
Retrieving to-do's from server...
To-do data:
ID: 1
User ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee
Message: Bake bread
ID: 2
User ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee
Message: Butter bread
Deleting a to-do...
Retrieving to-do's from server...
To-do data:
ID: 2
User ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee
Message: Butter bread
Editing a to-do...
Retrieving to-do's from server...
To-do data:
ID: 2
User ID: 00aa00aa-bb11-cc22-dd33-44ee44ee44ee
Message: Eat bread
Deleting remaining to-do...
Retrieving to-do's from server...
There are no to-do's in server

工作原理

守护程序应用使用 OAuth 2.0 客户端凭据授予来为自己获取访问令牌,而不是为用户获取访问令牌。 应用请求的访问令牌包含表示为角色的权限。 对于应用程序令牌,客户端凭据流使用此权限集来代替用户范围。 你之前在 Web API 中公开了这些应用程序权限,然后将它们授予守护程序应用。 本文中的守护程序应用使用适用于 .NET 的 Microsoft 身份验证库来简化获取令牌的过程。

在 API 端,Web API 必须验证访问令牌是否具有所需的权限(应用程序权限)。 Web API 会拒绝没有所需权限的访问令牌。