Azure 应用服务和 Azure Functions 中的身份验证和授权

Azure 应用服务提供内置身份验证(登录用户)和授权(提供对安全数据的访问权限)功能。 这些功能有时称为 Easy Auth。可以通过在 Web 应用、RESTful API、移动服务器和 函数中编写很少或无代码来让用户登录和访问数据。

注意

从 2024 年 6 月 1 日开始,新创建的应用服务应用可以生成使用命名约定 <app-name>-<random-hash>.<region>.azurewebsites.net 的唯一默认主机名。 例如: myapp-ds27dh7271aah175.westus-01.azurewebsites.net。 现有应用名称保持不变。

有关详细信息,请参阅关于创建具有唯一默认主机名的 Web 应用的博客文章

本文介绍应用服务如何帮助简化应用的身份验证和授权。

使用内置身份验证的原因

要实现身份验证和授权,可以使用所选 Web 框架中的捆绑安全功能,也可以编写自己的工具。 实现用于身份验证和授权的安全解决方案可能会花费大量精力。 你需要遵循行业最佳做法和标准。 你还需要通过最新的安全、协议和浏览器更新来确保解决方案始终是最新状态。

应用服务和 Azure Functions 的内置功能可以通过向联合身份验证标识提供程序提供现成身份验证来节省时间和精力,以便专注于应用程序的其余部分。

使用应用服务,可以将身份验证功能集成到 Web 应用或 API 中,而无需自行实现这些功能。 此功能直接内置于平台中,不需要任何特定的语言、SDK、安全专业知识或代码。 可以将它与多个登录提供程序集成,例如 Microsoft Entra、Facebook、Google 和 X。

应用可能需要支持更复杂的应用场景,例如 Visual Studio 集成或增量同意。 可以使用多种身份验证解决方案来支持这些应用场景。 若要了解详细信息,请参阅 身份验证方案和建议

标识提供者

应用服务使用 联合标识。 Microsoft或非Microsoft标识提供者为你管理用户标识和身份验证流。 默认提供以下五个标识提供者:

提供程序 登录终结点 操作说明指南
Microsoft Entra /.auth/login/aad 应用服务 Microsoft Entra 平台登录
Facebook /.auth/login/facebook 应用服务 Facebook 登录
谷歌 /.auth/login/google 应用服务 Google 登录
X /.auth/login/x 应用服务 X 登录
GitHub /.auth/login/github 应用服务 GitHub 登录
Apple /.auth/login/apple 通过 Apple 登录的应用服务登录(预览版)
任何 OpenID Connect 提供程序 /.auth/login/<providerName> 应用服务 OpenID Connect 登录

对其中一个提供程序配置此功能时,其登录终结点可用于用户身份验证,以及验证来自提供程序的身份验证令牌。 你可以轻松为用户提供任意数量的登录选项。

使用内置身份验证的注意事项

启用内置身份验证会导致应用程序的所有请求都自动重定向到 HTTPS,而不管应用服务配置设置如何强制实施 HTTPS。 可以使用 V2 配置中的 requireHttps 设置禁用此自动重定向。 但是,我们建议继续使用 HTTPS,并确保从未通过不安全的 HTTP 连接传输任何安全令牌。

可以使用应用服务进行身份验证,无论是否限制对站点内容和 API 的访问。 在 Web 应用的 “设置>身份验证>身份验证设置” 部分设置访问限制:

  • 要仅限经过身份验证的用户访问应用,请将“请求未经过身份验证时需执行的操作”设置为使用某个配置的标识提供程序登录。
  • 要进行身份验证但不限制访问权限,请将“请求未经过身份验证时需执行的操作”设置为“允许匿名请求(无操作)”。

重要说明

应为每个应用注册指定它自己的权限和同意。 通过对不同的部署槽位使用不同的应用注册,避免环境之间的权限共享。 在测试新代码时,这种做法可有助于防止出现影响生产应用的问题。

工作原理

功能体系结构

身份验证和授权中间件组件是平台的一项功能,与应用程序在同一虚拟机上运行。 启用它时,每个传入的 HTTP 请求都会在应用程序处理该组件之前通过该组件。

体系结构关系图,显示允许流量流向已部署的站点之前站点沙盒与标识提供者交互的过程。

平台中间件处理应用的几个操作:

  • 使用指定的标识提供者对用户和客户端进行身份验证
  • 验证、存储和刷新配置的标识提供者颁发的 OAuth 令牌
  • 管理经过身份验证的会话
  • 将标识信息插入 HTTP 请求标头

该模块独立于应用程序代码运行。 可以使用 Azure 资源管理器设置或使用配置文件对其进行配置。 不需要任何 SDK、特定编程语言,或者对应用程序代码进行更改。

Windows 上的功能体系结构(非容器部署)

身份验证和授权模块在应用程序所在的同一沙盒中作为本机 IIS 模块运行。 启用它时,每个传入的 HTTP 请求都会在应用程序处理它之前通过它。

Linux 和容器上的功能体系结构

身份验证和授权模块在独立于应用程序代码的单独容器中运行。 该模块使用 “大使”模式 与传入流量交互,以在 Windows 上执行类似的功能。 由于它未在进程中运行,因此无法直接与特定语言框架集成。 但应用所需的相关信息是通过请求标头传递的。

身份验证流

所有提供程序的身份验证流都是相同的。 这要看您是否想要使用提供程序的 SDK 登录。

  • 不使用提供程序 SDK:应用程序向应用服务委托联合登录。 此过程通常发生在浏览器应用中,其可以向用户显示提供程序的登录页面。 服务器代码管理登录过程,因此它也称为“服务器导向流”或“服务器流”。

    这种情况适用于使用嵌入式浏览器进行身份验证的浏览器应用和移动应用。

  • 使用提供程序 SDK:应用程序手动将用户登录到提供程序。 然后将身份验证令牌提交到应用服务进行验证。 此过程通常发生在无浏览器应用中,其无法向用户显示提供程序的登录页面。 应用程序代码管理登录过程,因此它也称为“客户端导向流”或“客户端流”。

    此情形适用于 REST API、Azure Functions 和 JavaScript 浏览器客户端,以及在登录过程中需要更高灵活性的浏览器应用。 它还适用于使用提供程序 SDK 登录用户的本机移动应用。

对于应用服务中受信任浏览器应用对应用服务或 Azure Functions 中另一 REST API 的调用,可以通过服务器导向流对其进行身份验证。 有关详细信息,请参阅自定义 Azure 应用服务身份验证中的登录和注销

下表显示了身份验证流的步骤。

步骤 不使用提供程序 SDK 使用提供程序 SDK
1.登录用户 提供程序将客户端重定向到 /.auth/login/<provider> 客户端代码使用提供程序的 SDK 直接登录用户,并接收身份验证令牌。 有关详细信息,请参阅提供程序的文档。
2.执行后身份验证 提供程序将客户端重定向到 /.auth/login/<provider>/callback 客户端代码将令牌从提供程序发布到/.auth/login/<provider> 进行验证。
3.建立经过身份验证的会话 应用服务将经过身份验证的 Cookie 添加到响应中。 应用服务将自身的身份验证令牌返回给客户端代码。
4.提供经过身份验证的内容 客户端在后续请求中包含身份验证 Cookie(由浏览器自动处理)。 客户端代码在 X-ZUMO-AUTH 标头中提供身份验证令牌。

对于客户端浏览器,应用服务可自动将所有未经身份验证的用户定向到 /.auth/login/<provider>。 还可以向用户提供一个或多个 /.auth/login/<provider> 链接,让他们使用所选的提供程序登录到你的应用。

授权行为

Azure 门户中,可以在传入请求未进行身份验证时为应用服务配置各种行为。 以下部分将介绍这些选项。

重要说明

默认情况下,此功能仅提供身份验证,而不提供授权。 除了在此处配置的任何检查之外,应用程序仍可能需要做出授权决策。

受限访问

  • 允许未经身份验证的请求:此选项会将对未经身份验证的流量授权推迟到由应用程序代码执行。 对于经过身份验证的请求,应用服务还会在 HTTP 标头中一起传递身份验证信息。

    使用此选项可以更灵活地处理匿名请求。 例如,可以向用户提供多个登录提供程序。 但是,必须编写代码。

  • 需要身份验证:此选项将拒绝任何未经身份验证的应用程序流量。 本文后面的未经身份验证的请求部分中指定了要采取的具体操作。

    使用此选项不需要在应用中编写任何身份验证代码。 可以通过检查用户的声明来处理较精细的授权,例如特定于角色的授权。

    警告

    以这种方式限制访问适用于对应用的所有调用,对于想要主页公开可用的应用程序来说,这可能是不可取的,就像在许多单页应用程序中一样。 如果需要异常,需要在 配置文件中配置排除的路径

    注意

    为组织中的用户使用 Microsoft 标识提供程序时,默认行为是 Microsoft Entra 租户中的任何用户都可以请求应用程序的令牌。 如果想要仅允许一组定义的用户访问应用,可以在 Microsoft Entra 中配置应用程序。 App 服务还提供了一些基本的内置授权检查,有助于进行一些验证。 若要详细了解 Microsoft Entra 中的授权,请参阅 Microsoft Entra 授权基础知识

为组织中的用户使用 Microsoft 标识提供者时,默认行为是 Microsoft Entra 租户中的任何用户都可以请求应用程序的令牌。 如果想要仅允许一组定义的用户访问应用,可以在 Microsoft Entra 中配置应用程序。 应用服务还提供了一些基本的内置授权检查,有助于进行一些验证。 若要详细了解 Microsoft Entra 中的授权,请参阅 Microsoft Entra 授权基础知识

未经身份验证的请求

  • HTTP 302 找到重定向:建议用于网站:将操作重定向到所配置的标识提供者之一。 在这些情况下,浏览器客户端将重定向到所选提供商的 /.auth/login/<provider>
  • HTTP 401 未授权:建议用于 API:如果匿名请求来自本机移动应用,则返回 响应。HTTP 401 Unauthorized 还可以针对所有请求将拒绝配置为 HTTP 401 Unauthorized
  • HTTP 403 被禁止:针对所有请求将拒绝配置为 HTTP 403 Forbidden
  • HTTP 404 未找到:针对所有请求将拒绝配置为 HTTP 404 Not found

令牌存储

应用服务提供内置令牌存储。 令牌存储是与 Web 应用、API 或本机移动应用的用户关联的令牌存储库。 对任何提供程序启用身份验证时,此令牌存储可立即供应用使用。

如果应用程序代码需要代表用户访问这些提供程序的数据,则通常必须编写代码来收集、存储和刷新应用程序中的这些令牌。 操作可能包括:

  • 发布到经过身份验证的用户的 Facebook 时间线。
  • 使用 Microsoft Graph API 读取用户的公司数据。

使用令牌存储,只需在需要令牌时才检索令牌;当令牌失效时,可以告知应用服务刷新令牌

将为经过身份验证的会话缓存 ID 令牌、访问令牌和刷新令牌。 只有关联的用户可以访问它们。

如果不需要在应用中使用令牌,可以在应用的“设置身份验证”>页上禁用令牌存储。

日志记录和跟踪

如果启用应用程序日志记录,身份验证和授权跟踪将直接显示在日志文件中。 如果出现意外的身份验证错误,查看现有的应用程序日志即可方便找到所有详细信息。

如果启用 失败的请求跟踪,则可以确切地查看身份验证和授权模块在失败的请求中可能扮演的角色。 在跟踪日志中,找到对名为 EasyAuthModule_32/64 的模块的引用。

跨网站请求伪造攻击的缓解措施

应用服务身份验证通过检查客户端请求是否符合以下条件来缓解跨网站请求伪造:

  • 它是通过会话 Cookie 进行身份验证的 POST 请求。
  • 请求来自已知浏览器(由 HTTP User-Agent 标头确定)。
  • HTTP Origin 或 HTTP Referer 标头缺失或不在已批准用于重定向的外部域已配置列表中。
  • HTTP Origin 标头缺失或不在配置的跨域资源共享 (CORS) 源列表中。

如果请求符合所有这些条件,应用服务身份验证会自动拒绝它。 可以通过在设置>身份验证>编辑身份验证设置>允许的外部重定向 URL中,将您的外部域添加到重定向列表中,来避开此缓解逻辑。

使用 Azure Front Door 的注意事项

在 Azure Front Door 或其他反向代理后面使用 Azure 应用服务进行身份验证时,请考虑执行以下操作。

禁用 Azure Front Door 缓存

为身份验证工作流禁用 Azure Front Door 缓存

使用 Azure Front Door 终结点进行重定向

应用服务在 Azure Front Door 公开时通常无法直接访问。 例如,通过在 Azure Front Door Premium 中使用 Azure 专用链接公开应用服务,可以阻止此行为。 为防止身份验证工作流将流量直接重定向回应用服务,必须将应用程序配置为重定向回 https://<front-door-endpoint>/.auth/login/<provider>/callback

确保应用服务使用正确的重定向 URI

在某些配置中,应用服务使用其完全限定的域名 (FQDN) 作为重定向 URI,而不是 Azure Front Door FQDN。 当客户端重定向到应用服务而不是 Azure Front Door 时,此配置会导致问题。 要更改它,请将 forwardProxy 设置为 Standard 以使应用服务遵循 Azure Front Door 设置的 X-Forwarded-Host 标头。

其他反向代理(如 Azure 应用程序网关或非 Microsoft 产品)可能使用不同的标头,并且需要不同的 forwardProxy 设置。

无法使用 Azure 门户更改 forwardProxy 配置。 需要使用 az rest

导出设置

az rest --uri /subscriptions/REPLACE-ME-SUBSCRIPTIONID/resourceGroups/REPLACE-ME-RESOURCEGROUP/providers/Microsoft.Web/sites/REPLACE-ME-APPNAME/config/authsettingsV2?api-version=2020-09-01 --method get > auth.json

更新设置

搜索:

"httpSettings": {
  "forwardProxy": {
    "convention": "Standard"
  }
}

确保将 convention 设置为 Standard,以遵循 Azure Front Door 使用的 X-Forwarded-Host 标头。

导入设置

az rest --uri /subscriptions/REPLACE-ME-SUBSCRIPTIONID/resourceGroups/REPLACE-ME-RESOURCEGROUP/providers/Microsoft.Web/sites/REPLACE-ME-APPNAME/config/authsettingsV2?api-version=2020-09-01 --method put --body @auth.json

有关应用服务身份验证的详细信息,请参阅:

相关示例如下所示: