Azure 容器应用中的身份验证和授权

Azure 容器应用提供内置的身份验证和授权功能(有时称为“简易身份验证”),以使用极少量的代码或无需使用任何代码来保护启用了外部入口的容器应用。

有关身份验证和授权的详细信息,请参阅以下适用于所选提供程序的指南。

为何使用内置身份验证?

你并非必须使用此功能进行身份验证和授权。 可以在所选的 Web 框架中使用捆绑的安全功能,也可以编写自己的实用程序。 但是,实现安全的身份验证(登录用户)和授权(提供对安全数据的访问)解决方案需要耗费大量精力。 必须确保遵循行业最佳做法和标准,并使实现保持最新。

适用于容器应用的内置身份验证功能通过联合标识提供者提供现成的身份验证,可为你节省时间和精力,使你能够专注于应用程序的其余部分。

  • Azure 容器应用提供对各种内置身份验证提供程序的访问。
  • 内置身份验证功能不需要熟悉任何特定语言、SDK、安全专业知识,甚至不需要编写任何代码。
  • 可与 Microsoft Entra ID 集成。

标识提供者

容器应用使用联合标识,在其中,第三方标识提供者会自动管理用户标识和身份验证流。 默认提供以下五个标识提供者:

提供程序 登录终结点 操作说明指南
Microsoft 标识平台 /.auth/login/aad Microsoft 标识平台
GitHub /.auth/login/github GitHub
任何 OpenID Connect 提供程序 /.auth/login/<providerName> OpenID Connect

使用其中的某个提供者时,可以使用登录终结点从该提供者进行用户身份验证和身份验证令牌验证。 你可以轻松为用户提供任意数量的提供者选项。

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

此功能只能与 HTTPS 结合使用。 确保在容器应用的入口配置中禁用 allowInsecure

可为容器应用配置身份验证,同时限制或不限制对站点内容和 API 的访问。 若要仅限已经过身份验证的用户访问应用,请将应用的“限制访问”设置指定为“需要身份验证”。 若要实施身份验证但不限制访问,请将应用的“限制访问”设置指定为“允许未经身份验证的访问”。

默认情况下,每个容器应用颁发自己唯一的 Cookie 或令牌以用于身份验证。 还可以提供自己的签名和加密密钥。

功能体系结构

身份验证和授权中间件组件是平台的一项功能,作为挎斗容器针对应用程序中的每个副本运行。 启用后,每个传入的 HTTP 请求将通过安全层,然后由应用程序处理。

An architecture diagram showing requests being intercepted by a sidecar container which interacts with identity providers before allowing traffic to the app container

此平台中间件为应用处理多项操作:

  • 使用指定的标识提供者对用户和客户端进行身份验证
  • 管理经过身份验证的会话
  • 将标识信息插入到 HTTP 请求头

身份验证和授权模块在独立于应用程序代码的单独容器中运行。 由于安全容器不在进程内运行,因此无法与特定的语言框架直接集成。 但是,应用所需的相关信息将在请求头中提供,如下所述。

身份验证流

身份验证流对于所有提供程序是相同的,但根据是否要使用提供程序的 SDK 登录而有所差别:

  • 使用提供程序 SDK(服务器导向的流或服务器流):应用程序将联合登录委托给容器应用。 浏览器应用通常采用委托,这会向用户显示提供程序的登录页。

  • 使用提供程序 SDK(客户端导向的流或客户端流):应用程序手动将用户登录到提供程序,然后将身份验证令牌提交给容器应用进行验证。 不向用户显示提供程序登录页的无浏览器应用通常采用此方法。 例如,使用提供程序的 SDK 将用户登录的本机移动应用。

可以使用服务器导向的流,对从容器应用中受信任浏览器应用向容器应用中另一个 REST API 发出的调用进行身份验证。 有关详细信息,请参阅自定义登录和注销

下表说明了身份验证流的步骤。

步骤 不使用提供程序 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 标头中一起传递身份验证信息。 应用可以使用标头中的信息来为请求做出授权决策。

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

  • 需要身份验证:此选项将拒绝任何未经身份验证的应用程序流量。 这个拒绝可以是指向已配置的标识提供者的重定向操作。 在这些情况下,浏览器客户端将重定向到所选提供商的 /.auth/login/<PROVIDER>。 如果匿名请求来自本机移动应用,则返回的响应为 HTTP 401 Unauthorized。 你还可针对所有请求将拒绝配置为 HTTP 401 UnauthorizedHTTP 403 Forbidden

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

    注意

    以这种方式限制访问适用于对应用的所有调用,对于想要主页公开可用的应用程序来说,这可能是不可取的,就像在许多单页应用程序中一样。

    注意

    默认情况下,Microsoft Entra 租户中的任何用户都可以从 Microsoft Entra ID 请求应用程序的令牌。 若要仅允许一组定义的用户访问应用,可以在 Microsoft Entra 中配置应用程序

自定义登录和注销

容器应用身份验证提供用于登录和注销的内置终结点。启用该功能后,这些终结点将在容器应用的 /.auth 路由前缀下提供。

使用多个登录提供程序

门户配置不会提供向用户显示多个登录提供程序的统包方式。 但是,将此功能添加到应用并不困难。 步骤概括如下:

首先,在 Azure 门户中的“身份验证/授权”页上,配置想要启用的每个标识提供者。

在“请求未经身份验证时需执行的操作”中,选择“允许匿名请求(无操作)”。

在登录页、导航栏或应用的其他任何位置中,将一个登录链接添加到已启用的每个提供程序 (/.auth/login/<provider>)。 例如:

<a href="/.auth/login/aad">Log in with the Azure Identity Platform</a>

当用户选择某个链接时,将向用户显示相应提供程序的 UI。

若要将登录后用户重定向到自定义 URL,请使用 post_login_redirect_uri 查询字符串参数(不要与标识提供者配置中的重定向 URI 混淆)。 例如,若要在登录后将用户导航至 /Home/Index,使用以下 HTML 代码:

<a href="/.auth/login/<provider>?post_login_redirect_uri=/Home/Index">Log in</a>

客户端主导的登录

在客户端主导的登录中,应用程序使用特定于提供者的 SDK 将用户登录到标识提供者。 然后,应用程序代码使用 HTTP POST 请求将生成的身份验证令牌提交给容器应用进行验证(请参阅身份验证流)。

若要验证提供程序令牌,必须首先为容器应用配置所需的提供程序。 在运行时,从你的提供程序检索身份验证令牌后,将令牌发布到 /.auth/login/<provider> 进行验证。 例如:

POST https://<hostname>.azurecontainerapps-dev.cn.io/.auth/login/aad HTTP/1.1
Content-Type: application/json

{"id_token":"<token>","access_token":"<token>"}

令牌格式根据提供程序而略有不同。 有关详细信息,请参阅下表:

提供程序值 请求正文中必需的 注释
aad {"access_token":"<ACCESS_TOKEN>"} id_tokenrefresh_tokenexpires_in 属性是可选项。
microsoftaccount {"access_token":"<ACCESS_TOKEN>"}{"authentication_token": "<TOKEN>" authentication_token 优先于 access_tokenexpires_in 属性为可选。
从 Live 服务请求令牌时,将始终请求 wl.basic 作用域。

如果提供程序令牌成功通过验证,则 API 将在响应正文中返回一个 authenticationToken,这是你的会话令牌。

{
    "authenticationToken": "...",
    "user": {
        "userId": "sid:..."
    }
}

获得此会话令牌后,你可以通过向 HTTP 请求中添加 X-ZUMO-AUTH 标头来访问受保护的应用资源。 例如:

GET https://<hostname>.azurecontainerapps-dev.cn.io/api/products/1
X-ZUMO-AUTH: <authenticationToken_value>

注销会话

用户可通过向应用的 /.auth/logout 终结点发送 GET 请求来启动注销。 GET 请求执行以下操作:

  • 清除当前会话中的身份验证 Cookie。
  • 从令牌存储中删除当前用户的令牌。
  • 对于 Microsoft Entra ID,请对标识提供者执行服务器端注销。

以下是网页中一个简单的注销链接:

<a href="/.auth/logout">Sign out</a>

默认情况下,成功注销后,客户端会重定向到 URL /.auth/logout/done。 通过添加 post_logout_redirect_uri 查询参数可更改注销后的重定向页面。 例如:

GET /.auth/logout?post_logout_redirect_uri=/index.html

建议对 post_logout_redirect_uri 的值进行编码。

使用完全限定的 URL 时,URL 必须托管在同一个域中。

在应用程序代码中访问用户声明

对于所有语言框架,容器应用会在应用程序代码中传入的令牌中的声明。 声明将注入到请求头中,无论请求是否来自经过身份验证的最终用户或客户端应用程序,都会提供这些头。 不允许外部请求设置这些头,因此,只会提供容器应用设置的头。 部分标头示例如下:

  • X-MS-CLIENT-PRINCIPAL-NAME
  • X-MS-CLIENT-PRINCIPAL-ID

使用任何语言或框架编写的代码均可从这些标头获取所需信息。

注意

不同的语言框架可能会以不同格式(例如小写或标题字首大写)向应用代码显示这些标头。

后续步骤

有关保护容器应用的详细信息,请参阅以下文章。