使用 Microsoft Entra 应用程序代理来安全地访问本地 API

你可以使用本地运行的业务逻辑 API,也可以使用云中虚拟机上托管的业务逻辑 API。 本机 Android、iOS、Mac 或 Windows 应用需要与 API 终结点交互才能使用数据或提供用户交互功能。 通过使用 Microsoft Entra 应用程序代理和 Microsoft 身份验证库 (MSAL),本机应用可安全访问本地 API。 与开启防火墙端口和控制应用层身份验证和授权相比,Microsoft Entra 应用程序代理是一种更快速、更安全的解决方案。

本文逐步讲解如何设置 Microsoft Entra 应用程序代理解决方案,以托管本机应用可以访问的 Web API 服务。

概述

下图显示了发布本地 API 的传统方法。 此方法需要开启传入端口 80 和 443。

Traditional API access

下图显示如何使用 Microsoft Entra 应用程序代理安全发布 API,而无需开启任何传入端口:

Microsoft Entra application proxy API access

Microsoft Entra 应用程序代理是此解决方案的主干,可用作 API 访问的公共终结点,并提供身份验证和授权。 你可以使用 Microsoft 身份验证库 (MSAL) 中的多个库,从大量平台访问 API。

由于 Microsoft Entra 应用程序代理身份验证和授权是基于 Microsoft Entra ID 实现的,因此可以使用 Microsoft Entra 条件访问,确保只有受信任的设备才可访问通过应用程序代理发布的 API。 对于桌面设备,可使用 Microsoft Entra 联接或 Microsoft Entra 混合联接设备,而对于设备,可使用 Intune 托管设备。 还可以利用 Microsoft Entra ID P1 或 P2 功能,例如 Microsoft Entra 多重身份验证,以及由机器学习提供支持的 Microsoft Entra ID 保护安全功能。

先决条件

若要完成本演练,你需要:

通过应用程序代理发布 API

若要通过应用程序代理在 Intranet 外部发布 API,请遵循与发布 Web 应用相同的模式。 有关详细信息,请参阅教程:添加本地应用程序以通过 Microsoft Entra ID 应用程序代理进行远程访问

通过应用程序代理发布 SecretAPI Web API:

  1. 生成示例 SecretAPI 项目并将其发布为本地计算机或 Intranet 上的 ASP.NET Web 应用。 请确保可以在本地访问 Web 应用。

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

  3. 浏览到“标识”>“应用程序”>“企业应用程序”。

  4. 在“企业应用程序 - 所有应用程序”页的顶部,选择“新建应用程序”。

  5. 在“浏览 Microsoft Entra 库”页上,找到“本地应用程序”部分,然后选择“添加本地应用程序”。 随即显示“添加自己的本地应用程序”页。

  6. 如果尚未安装应用程序代理连接器,系统会提示你安装。 选择“下载应用程序代理连接器”,以下载并安装连接器。

  7. 安装应用程序代理连接器后,请在“添加自己的本地应用程序”页上执行以下操作:

    1. 在“名称”旁边,输入“SecretAPI”。

    2. 在“内部 URL”旁边,输入用于从 Intranet 中访问 API 的 URL。

    3. 确保将“预身份验证”设置为“Microsoft Entra ID”。

    4. 在页面顶部选择“添加”,等待应用完成创建。

    Add API app

  8. 在“企业应用程序 - 所有应用程序”页上,选择“SecretAPI”应用。

  9. 在“SecretAPI - 概述”页上,选择左侧导航栏中的“属性”。

  10. 如果不希望在“MyApps”面板中向最终用户提供 API,则在“属性”页底部将“对用户可见”设置为“否”,然后选择“保存”。

    Not visible to users

你已通过 Microsoft Entra 应用程序代理发布了 Web API。 现在,添加可以访问应用的用户。

  1. 在“SecretAPI - 概述”页上,选择左侧导航栏中的“用户和组”。

  2. 在“用户和组”页上,选择“添加用户”。

  3. 在“添加分配”页上,选择“用户和组”。

  4. 在“用户和组”页上,搜索并选择可以访问应用的用户,至少应包括你自己。 选择所有用户后,选择“选择”。

    Select and assign user

  5. 回到“添加分配”页上,选择“分配”。

注意

对于使用集成 Windows 身份验证的 API,可能还需要执行其他步骤

注册本机应用并授予对 API 的访问权限

本机应用是为在特定平台或设备上使用而开发的程序。 在本机应用可以连接和访问 API 之前,必须在 Microsoft Entra ID 中进行注册。 以下步骤演示如何注册本机应用,并授予它访问通过应用程序代理所发布 Web API 的权限。

注册 AppProxyNativeAppSample 本机应用:

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

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

  3. 选择“新注册”。

  4. 在“注册应用程序”页面上:

    1. 在“名称”下,输入 AppProxyNativeAppSample。

    2. 在“支持的帐户类型”下,选择“仅此组织目录中的帐户(仅 Contoso - 单一租户)”。

    3. 在“重定向 URL”下,使用下拉列表选择“公共客户端/本机(移动和桌面)”,然后输入 *https://login.microsoftonline.com/common/oauth2/nativeclient *。

    4. 选择“注册”,并等待应用成功注册。

      New application registration

你现在已经在 Microsoft Entra ID 中注册了 AppProxyNativeAppSample 应用。 为本机应用提供访问 SecretAPI Web API 的权限:

  1. 在“应用注册”页上,选择“AppProxyNativeAppSample”应用。

  2. 在“AppProxyNativeAppSample”页上,选择左侧导航栏中的“API 权限”。

  3. 在“API 权限”页上,选择“添加权限”。

  4. 在第一个“请求获取 API 权限”页上,选择“我的组织使用的 API”选项卡,然后搜索并选择“SecretAPI”。

  5. 在下一个“请求获取 API 权限”页上,选中“user_impersonation”旁边的复选框,然后选择“添加权限”。

    Select an A P I.

  6. 返回“API 权限”页,你可以选择“为 Contoso 授予管理员许可”,以防止其他用户必须单独同意该应用。

配置本机应用代码

最后一步是配置本机应用。 以下步骤中使用的代码片段基于将 Microsoft 身份验证库添加到代码中(.NET C# 示例)。 此示例中的代码是自定义的。 必须将此代码添加到 NativeClient 示例应用程序中的 Form1.cs 文件中,这会导致 MSAL 库获取用于请求 API 调用的令牌,并将其附加为请求中的标头。

注意

示例应用程序使用 Azure Active Directory 身份验证库 (ADAL)。 阅读如何将 MSAL 添加到你的项目。 记得将对 MSAL 的引用添加到此类,并删除 ADAL 引用。

配置本机应用代码:

  1. 在 Form1.cs 中,将命名空间 using Microsoft.Identity.Client; 添加到代码。

  2. 将命名空间 using Microsoft.IdentityModel.Clients.ActiveDirectory; 从代码中删除。

  3. 删除第 26 行和第 30 行,因为不再需要这些行。

  4. GetTodoList()方法的内容替换为以下代码片段:

    // Acquire Access Token from Azure AD for Proxy Application
    var clientApp = PublicClientApplicationBuilder
        .Create(clientId)
        .WithDefaultRedirectUri() // Will automatically use the default URI for native app
        .WithAuthority(authority)
        .Build();
    var accounts = await clientApp.GetAccountsAsync();
    var account = accounts.FirstOrDefault();
    
    var scopes = new string[] { todoListResourceId + "/user_impersonation" };
    
    AuthenticationResult authResult;
    try
    {
        authResult = await clientApp.AcquireTokenSilent(scopes, account).ExecuteAsync();
    }
    catch (MsalUiRequiredException ex)
    {
        authResult = await clientApp.AcquireTokenInteractive(scopes).ExecuteAsync();
    }
    
    if (authResult != null)
    {
        // Use the Access Token to access the Proxy Application
        var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
        // Call the To Do list service
        var response = await httpClient.GetAsync(todoListBaseAddress + "/api/values/4");
        var responseString = await response.Content.ReadAsStringAsync();
        MessageBox.Show(responseString);
    }
    

若要配置本机应用以连接到 Microsoft Entra ID 并调用 API 应用代理,请在 NativeClient 示例应用的 App.config 文件中将占位符值更新为来自 Microsoft Entra ID 的值:

  1. 将“目录(租户) ID”粘贴到 <add key="ida:Tenant" value="" /> 字段中。 你可以从任一应用的“概述”页中找到并复制此值 (GUID)。

  2. 将 AppProxyNativeAppSample“应用程序(客户端) ID”粘贴到 <add key="ida:ClientId" value="" /> 字段中。 可以从 AppProxyNativeAppSample 的“概述”页(位于“管理”下的左侧导航)查找并复制此值(一个唯一标识符)。

  3. 此步骤是可选的,因为 MSAL 使用方法 PublicClientApplicationBuilder.WithDefaultRedirectUri() 插入建议的回复 URI。 将 AppProxyNativeAppSample“重定向 URI”粘贴到 <add key="ida:RedirectUri" value="" /> 字段中。 可以从 AppProxyNativeAppSample 的“授权”页(位于“管理”下的左侧导航)查找并复制此值(一个统一资源标识符)。

  4. 将 SecretAPI“应用程序 ID URI”粘贴到 <add key="todo:TodoListResourceId" value="" /> 字段中。 这与下面的 todo:TodoListBaseAddress 值相同。 可以从 SecretAPI 的“公开 API”页(位于“管理”下的左侧导航)查找并复制此值(一个统一资源标识符)。

  5. 将 SecretAPI“主页 URL”粘贴到 <add key="todo:TodoListBaseAddress" value="" /> 字段中。 可以从 SecretAPI 的“品牌打造和属性”(位于左侧导航中的“管理”下)查找并复制此值(一个 URL)。

注意

如果解决方案未生成并报告错误“Resx 文件无效”,请在解决方案资源管理器中,展开“属性”,右键单击“Resources.resx”,然后选择“查看代码”。 为第 121 行到第 123 行添加注释。

配置参数后,生成并运行本机应用。 选择“登录”按钮时,应用程序会让你登录,然后显示成功屏幕,以确认它已成功连接到 SecretAPI。

Screenshot shows a message Secret A P I Successful and an OK button.

后续步骤