你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
Azure 应用服务提供高度可缩放、自修补的 Web 托管服务。 应用服务具有对用户身份验证和授权的内置支持。 本教程介绍如何通过应用服务身份验证和授权来确保应用的安全性。 它使用带有视图前端的 Express.js。 应用服务身份验证和授权支持所有语言运行时。 可以按照本教程中的说明了解如何将其应用于首选语言。
Azure 应用程序服务提供使用 Linux 操作系统的高度可扩展且自动修补的 Web 托管服务。 应用服务具有对用户身份验证和授权的内置支持。 本教程介绍如何通过应用服务身份验证和授权来确保应用的安全性。 它使用带有视图前端的 Express.js。 应用服务身份验证和授权支持所有语言运行时。 可以按照本教程中的说明了解如何将其应用于首选语言。
此过程中的身份验证由 Azure 应用服务在托管平台层提供。 必须部署前端和后端应用,并配置此 Web 应用的身份验证才能成功使用。
完成此方案后,请继续学习下一教程,了解如何以经过身份验证的用户身份连接到 Azure 服务。 常见方案包括作为拥有特定能力或有权访问特定表或文件的用户访问 Azure 存储或数据库。
在本教程中,你将:
- 启用内置身份验证和授权
- 确保应用能够防范未经身份验证的请求
- 使用 Microsoft Entra ID 作为标识提供程序
- 代表登录的用户访问远程应用
- 使用令牌身份验证确保服务间调用的安全性
- 使用服务器代码中的访问令牌
先决条件
如果没有 Azure 帐户,请在开始前创建一个免费帐户。
在 Azure Cloud Shell 中使用 Bash 环境。 有关详细信息,请参阅开始使用 Azure Cloud Shell。
如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。
如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅 使用 Azure CLI 向 Azure 进行身份验证。
出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用和管理 Azure CLI 的扩展。
运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade。
获取用户个人资料
前端应用配置为安全地使用后端 API。 前端应用程序为用户提供 Microsoft 登录,然后允许用户从后端获取其虚假个人资料。 本教程使用虚构的个人资料,以简化完成整个场景的步骤。
在源代码在前端运行之前,应用服务会从应用服务 x-ms-token-aad-access-token
标头注入经过身份验证的 accessToken
。 然后,前端源代码访问并发送到 accessToken
后端服务器。 前端服务器将令牌作为 bearerToken
发送,以安全地访问后端 API。 后端服务器在将 bearerToken
传递给后端源代码之前对其进行验证。 后端源代码收到bearerToken
后,可以使用它。
在本系列 下一教程 中,将 bearerToken
交换为一个令牌,其中包含用于访问 Microsoft Graph API 的范围。 Microsoft Graph API 返回用户的档案信息。
克隆示例应用程序
在 Azure Cloud Shell 中,运行下列命令以克隆示例存储库。
git clone https://github.com/Azure-Samples/js-e2e-web-app-easy-auth-app-to-app
创建和部署应用
创建资源组、Web 应用计划和 Web 应用,然后在单个步骤中部署。
切换到
frontend
Web 应用目录。cd js-e2e-web-app-easy-auth-app-to-app/frontend
使用 az webapp up 命令创建和部署前端 Web 应用。 Web 应用名称必须全局唯一。 将
<front-end-app-name>
替换为唯一名称。az webapp up --resource-group myAuthResourceGroup --name <front-end-app-name> --plan myPlan --sku FREE --os-type Windows --location "West Europe" --runtime "NODE:20LTS"
切换到
backend
Web 应用目录。cd ../backend
将后端 Web 应用部署到同一资源组和应用计划。 Web 应用名称必须全局唯一。 将
<back-end-app-name>
替换为唯一的字母和数字字符串。az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name> --plan myPlan --os-type Windows --location "West Europe" --runtime "NODE:20LTS"
切换到
frontend
Web 应用目录。cd frontend
使用 az webapp up 命令创建和部署前端 Web 应用。 Web 应用名称必须全局唯一。 将
<front-end-app-name>
替换为唯一的字母和数字串。az webapp up --resource-group myAuthResourceGroup --name <front-end-app-name> --plan myPlan --sku FREE --location "West Europe" --os-type Linux --runtime "NODE:20-lts"
将目录更改为
backend
Web 应用目录。cd ../backend
将后端 Web 应用部署到同一资源组和应用计划。 Web 应用名称必须全局唯一。 将
<back-end-app-name>
替换为唯一的字母和数字字符串。az webapp up --resource-group myAuthResourceGroup --name <back-end-app-name> --plan myPlan --sku FREE --location "West Europe" --runtime "NODE:16-lts"
配置应用设置
前端应用程序需要知道 API 请求的后端应用程序的 URL。 使用以下 Azure CLI 命令配置应用设置。 URL 应为 https://<back-end-app-name>.azurewebsites.net
.
az webapp config appsettings set --resource-group myAuthResourceGroup --name <front-end-app-name> --settings BACKEND_URL="https://<back-end-app-name>.azurewebsites.net"
前端调用后端
访问前端应用,并从后端返回 虚假 个人资料。 此作验证前端是否成功从后端请求配置文件,并且后端返回配置文件。
在浏览器中打开前端 Web 应用:
https://<front-end-app-name>.azurewebsites.net
。选择 “获取用户的个人资料 ”链接。
查看从后端Web应用返回的虚假个人资料。
withAuthentication
值为 false 表示尚未设置身份验证。
配置身份验证
在本部分中,为两个 Web 应用启用身份验证和授权。 本教程使用 Microsoft Entra ID 作为标识提供程序。
还可以将前端应用配置为:
- 授予前端应用对后端应用的访问权限
- 对应用服务进行配置,使之返回可用令牌
- 在代码中使用令牌
有关详细信息,请参阅为应用程序服务应用程序配置 Microsoft Entra 身份验证。
为后端应用启用身份验证和授权
在 Azure 门户中,搜索并选择“资源组”。
在“资源组”中,查找并选择资源组。 在 “概述”中,选择后端应用。
在后端应用的左侧菜单中,选择“设置身份验证”>,然后选择“添加标识提供者”。
在“添加标识提供者”页中,选择Microsoft以使用Microsoft和Microsoft Entra 标识登录。
为 客户端机密过期选择一个值。
对于其他值,请接受默认设置并选择“ 添加”。
这时会显示“身份验证”页。 将 Microsoft Entra 应用程序的客户端 ID 复制到记事本。 稍后需要用到此值。
如果在此处停止,则具有应用服务身份验证和授权安全的自包含应用。 其余部分介绍如何通过将经过身份验证的用户从前端 流向 后端来保护多个应用解决方案。
为前端应用启用身份验证和授权
在 Azure 门户中,搜索并选择“资源组”。
在“资源组”中,查找并选择资源组。 在 “概述”中,选择前端应用。
在前端应用的左侧菜单中,选择“设置身份验证”>,然后选择“添加标识提供者”。
在“添加标识提供者”页中,选择Microsoft以使用Microsoft和Microsoft Entra 标识登录。
为 客户端机密过期选择一个值。 对于其他值,请接受默认设置并选择“ 添加”。
这时会显示“身份验证”页。 将 Microsoft Entra 应用程序的客户端 ID 复制到记事本。 稍后需要用到此值。
授予前端应用对后端应用的访问权限
你为这两个应用启用了身份验证和授权。 要完成身份验证,需要执行以下三项操作:
- 授予前端应用对后端应用的访问权限
- 对应用服务进行配置,使之返回可用令牌
- 在代码中使用令牌
提示
如果遇到错误并重新配置应用的身份验证/授权设置,令牌存储中的令牌可能无法从新设置重新生成。 若要确保令牌重新生成,需要注销并重新登录到应用。 一种方法是在专用模式下使用浏览器。 更改应用中的设置后,关闭并重新打开处于专用模式的浏览器。
在本部分中,您将代表用户授予前端应用对后端应用的访问权限。 从技术上说,为前端的 AD 应用程序 授予代表用户访问后端 AD 应用程序 的权限。
在前端应用的 “身份验证 ”页中,在 “标识提供者”下,选择前端应用名称。 此应用注册是自动为你生成的。
在左侧菜单中选择 “管理>API 权限 ”。
选择“添加权限”,然后选择“我的 API”。
在后端应用的 “请求 API 权限 ”页中,选择 “委派的权限 ”并 user_impersonation,然后选择“ 添加权限”。
对应用服务进行配置,使之返回可用的访问令牌
前端应用现在具有作为已登录用户访问后端应用所需的权限。 在本部分中,配置应用服务身份验证和授权,以便提供用于访问后端的可用访问令牌。 执行此步骤时,需要后端的客户端 ID,该 ID 是从为后端应用启用身份验证和授权复制的。
在 Cloud Shell 中,在前端应用中运行以下命令,将 scope
参数添加到身份验证设置 identityProviders.azureActiveDirectory.login.loginParameters
。 替换 <front-end-app-name> 和 <back-end-client-id>。
az extension add --name authV2
authSettings=$(az webapp auth show -g myAuthResourceGroup -n <front-end-app-name>)
authSettings=$(echo "$authSettings" | jq '.properties' | jq '.identityProviders.azureActiveDirectory.login += {"loginParameters":["scope=openid offline_access api://<back-end-client-id>/user_impersonation"]}')
az webapp auth set --resource-group myAuthResourceGroup --name <front-end-app-name> --body "$authSettings"
这些命令添加一个具有其他自定义作用域的属性 loginParameters
。 下面解释了请求的范围:
- 默认情况下,应用服务已请求
openid
。 有关详细信息,请参阅 OpenID Connect 范围。 - 为了方便起见,此处包括offline_access权限,如果您想要刷新令牌。
api://<back-end-client-id>/user_impersonation
是后端应用注册中公开的 API。 它是一个范围,为你提供 JWT,其将后端应用作为令牌受众包含在内。
提示
- 若要查看 Azure 门户中的范围
api://<back-end-client-id>/user_impersonation
,请转到后端应用的 “身份验证 ”页,选择 标识提供者下的链接,然后在左侧菜单中选择“ 公开 API ”。 - 若要改用 Web 界面配置所需的范围,请参阅 “刷新身份验证令牌”。
- 某些范围需要管理员同意或用户同意。 当用户在浏览器中登录到前端应用时,此要求会导致同意请求页面出现。 若要避免此许可页,请在 “公开 API ”页中将前端的应用注册添加为授权客户端应用程序。 选择 “添加客户端应用程序 ”并提供前端应用注册的客户端 ID。
现在已配置好了应用。 前端现在已准备好使用适当的访问令牌访问后端。
若要了解如何为其他提供程序配置访问令牌,请参阅刷新标识提供者令牌。
将后端应用服务配置为仅接受来自前端应用服务的令牌
还应将后端应用服务配置为仅接受来自前端应用服务的令牌。 不执行此配置会导致 403:将令牌从前端传递到后端时出现 “禁止访问”错误 。
可以使用上一步中使用的同一 Azure CLI 过程来实现此方法。
获取前端应用服务的
appId
。 可以在前端应用服务的 “身份验证 ”页上获取此值。运行以下 Azure CLI,并替换
<back-end-app-name>
和<front-end-app-id>
。
authSettings=$(az webapp auth show -g myAuthResourceGroup -n <back-end-app-name>)
authSettings=$(echo "$authSettings" | jq '.properties' | jq '.identityProviders.azureActiveDirectory.validation.defaultAuthorizationPolicy.allowedApplications += ["<front-end-app-id>"]')
az webapp auth set --resource-group myAuthResourceGroup --name <back-end-app-name> --body "$authSettings"
前端调用经过身份验证的后端
前端应用需要将具有正确 user_impersonation
作用域的用户身份验证传递给后端。 以下步骤查看了为此功能提供的示例代码。
查看前端应用的源代码:
使用前端应用服务注入的
x-ms-token-aad-access-token
标头以编程方式获取用户的 accessToken。// ./src/server.js const accessToken = req.headers['x-ms-token-aad-access-token'];
使用标头
Authentication
中的 accessToken 作为bearerToken
值。// ./src/remoteProfile.js // Get profile from backend const response = await fetch(remoteUrl, { cache: "no-store", // no caching -- for demo purposes only method: 'GET', headers: { 'Authorization': `Bearer ${accessToken}` } }); if (response.ok) { const { profile } = await response.json(); console.log(`profile: ${profile}`); } else { // error handling }
本教程返回虚构配置文件以简化方案。 本系列中的下一个教程演示了如何将后端
bearerToken
交换为具有下游 Azure 服务(如 Microsoft Graph)范围的新令牌。
后端将个人资料返回给前端
如果前端的请求未获得授权,后端应用服务会在请求到达应用程序代码 之前 拒绝请求,并显示 401 HTTP 错误代码。 当到达后端代码时,由于它包含授权令牌,因此提取 bearerToken
以获取 accessToken
。
查看后端应用的源代码:
// ./src/server.js
const bearerToken = req.headers['Authorization'] || req.headers['authorization'];
if (bearerToken) {
const accessToken = bearerToken.split(' ')[1];
console.log(`backend server.js accessToken: ${!!accessToken ? 'found' : 'not found'}`);
// TODO: get profile from Graph API
// provided in next article in this series
// return await getProfileFromMicrosoftGraph(accessToken)
// return fake profile for this tutorial
return {
"displayName": "John Doe",
"withAuthentication": !!accessToken ? true : false
}
}
浏览到应用
在浏览器中使用前端网站。 该 URL 为
https://<front-end-app-name>.azurewebsites.net/
。浏览器向 Web 应用请求身份验证。 完成身份验证。
身份验证完成后,前端应用程序将返回应用的主页。
选择“获取用户配置文件”。 此操作会将您在承载令牌中的身份验证传递到后端。
后端使用虚假的硬编码个人资料名称进行响应:
John Doe
。withAuthentication
true 的值表示现在已设置身份验证。
清理资源
在前面的步骤中,你在资源组中创建了 Azure 资源。
通过在 Cloud Shell 中运行以下命令来删除资源组。 此命令可能需要花费一点时间运行。
az group delete --name myAuthResourceGroup
使用身份验证应用的客户端 ID,你之前在后端和前端应用的 部分中找到并记下了此 ID。
Enable authentication and authorization
删除前端和后端应用的应用注册。
# delete app - do this for both frontend and backend client ids az ad app delete <client-id>
常见问题
如何实现在本地开发计算机上测试此身份验证?
此过程中的身份验证由 Azure 应用服务在托管平台层提供。 没有等效的仿真器。 必须部署前端和后端应用,并为每个应用配置身份验证才能使用身份验证。
应用未显示虚假个人资料,如何调试它?
当此应用程序未返回虚假个人资料时,前端和后端应用均具有 /debug
路由来帮助调试身份验证。 前端调试路由提供了用于验证的关键部分:
环境变量:
BACKEND_URL
已正确配置为https://<back-end-app-name>.azurewebsites.net
。 请勿包含尾随正斜杠或路由。
HTTP 标头:
x-ms-token-*
标头已注入。
将显示已登录用户的 Microsoft Graph 配置文件名称。
前端应用的令牌范围具有
user_impersonation
。 如果范围不包含此值,则可能是计时问题。 在 Azure 资源中验证前端应用login
的参数。 等待几分钟后才能复制身份验证。
应用程序源代码是否已正确部署到每个 Web 应用?
在 Web 应用的 Azure 门户中,依次选择 “开发工具>高级工具”、“ Go”。 此操作将打开新的浏览器选项卡或窗口。
在新浏览器选项卡中,选择“ 浏览目录>站点 wwwroot”。
验证目录中的以下内容:
- package.json
- node_modules.tar.gz
- /src/index.js
验证 package.json
name
属性是否与 Web 名称相同,frontend
或者backend
。如果更改了源代码,并且需要重新部署,请使用具有该应用的 package.json 文件的目录中的 az webapp up 命令。
应用程序是否正确启动?
请求主页时,这两个 Web 应用都应返回一些内容。 如果无法访问 Web 应用上的 /debug
,则表示该应用无法正常启动。 查看该 Web 应用的错误日志。
- 在 Web 应用的 Azure 门户中,依次选择 “开发工具>高级工具”、“ Go”。 此操作将打开新的浏览器标签页或窗口。
- 在新浏览器选项卡中,选择“ 浏览目录>部署日志”。
- 查看每个日志以查找任何报告的问题。
前端应用能否与后端应用通信?
由于前端应用从服务器源代码调用后端应用,因此此行为不是在浏览器网络流量中看到的内容。 使用以下列表确定后端用户资料请求成功:
如果已到达后端 Web 应用,后端 Web 应用会将任何错误返回到前端应用。 如果未到达,前端应用将报告状态代码和消息。
- 401:用户未正确通过身份验证。 此消息可以指示未正确设置范围。
- 404:服务器的 URL 与服务器具有的路由不匹配
使用后端应用的流式处理日志来观察你对用户个人资料发出前端请求的情况。 源代码
console.log
中有调试信息,有助于确定故障发生的位置。
前端令牌过期时会发生什么情况?
访问令牌在一段时间后会过期。 若要了解如何在不需用户通过应用重新进行身份验证的情况下刷新访问令牌,请参阅刷新标识提供者令牌。
如果我在前端应用上有一个基于浏览器的应用,它可以直接与后端对话吗?
这种方法要求服务器代码将访问令牌传递给客户端浏览器中运行的 JavaScript 代码。 由于无法保护浏览器中的访问令牌,因此不建议使用此方法。 目前,我们建议使用后端为前端模式。
如果应用于本教程中的示例,前端应用上的浏览器代码将在经过身份验证的会话中将其服务器代码作为中介进行 API 调用。 然后,前端应用上的服务器代码将使用 x-ms-token-aad-access-token
作为持有者令牌,对后端应用进行 API 调用。 从浏览器代码到服务器代码的所有调用均受经过身份验证的会话保护。
后续步骤
转到下一教程,了解如何使用此用户的标识访问 Azure 服务。