博客 | NGINX

使用 Okta 和 NGINX Ingress Controller 为 Kubernetes 实现 OpenID Connect 身份验证

NGINX-F5-horiz-black-type-RGB 的一部分
Amir Rawdat 缩略图
阿米尔·罗达特
2021 年 9 月 22 日发布

我们已经多次写过,在当今勒索软件和机器人驱动攻击的环境下,保护您的应用程序和 API 的重要性。 与Web应用防火墙(WAF) 等机制一起,验证用户身份和强制授权控制是保护您的业务应用的重要方法。

实现身份验证和授权最直接的方式是在应用本身中。 当您的用户群较小并且您的应用不需要频繁更新时,这种方法虽然可行,但一旦规模扩大,这种方法很快就会变得难以为继。 首先,当您的用户必须记住许多应用程序的每个不同的帐户名和密码时,他们在尝试登录时经常会收到令人沮丧的“用户名或密码不正确”的消息,导致他们求助于不安全的解决方案,例如容易猜到的“abc123”密码。 我们都见过显示器上贴满了带有密码提醒的 Post‑it® 便签!

单点登录 (SSO) 技术可以部分解决这些问题,通过消除所有单独的用户名和密码,转而采用一组凭证。 用户只需通过身份提供商 (IdP) 登录一次即可访问许多应用程序。 但是开发人员仍然必须在他们的应用程序中包含代码来与 SSO 系统交互,这可能非常具有挑战性,特别是在应用变得越来越复杂时。

随着组织规模不断扩大,需要满足不断增长的用户群的需求,从应用层卸载与应用程序功能无关的需求(例如身份验证和授权)变得至关重要。 Kubernetes中集中身份验证和授权的理想位置是Ingress 控制器,它可以仔细检查进入集群的所有流量并将其路由到适当的服务。 这使开发人员摆脱了构建、维护和复制身份验证逻辑的负担,他们可以使用本机 Kubernetes API 轻松地在入口层利用 SSO 技术。

在此博客中,我们展示了如何使用基于 NGINX Plus 的NGINX Ingress Controller 作为中继方来实现成熟的 SSO 解决方案,并使用 Okta 作为预配置的身份提供者 (IdP) 支持OIDC 授权码流

笔记: 基于 NGINX 开源的 NGINX Ingress Controller 不提供此功能。

先决条件

本博客假设您有在 Kubernetes 环境中操作的经验。 此外,您还需要以下信息:

  • Kubernetes 环境- NGINX Ingress Controller 在原始 Kubernetes 以及众多 Kubernetes 平台上均受支持,包括 Amazon Elastic Kubernetes (EKS)、裸机、Google Kubernetes Engine (GKE)、Microsoft Azure Kubernetes Service (AKS)、Rancher Kubernetes Engine 和 Red Hat OpenShift。
  • 基于 NGINX Plus 的 NGINX Ingress Controller – 您必须拥有基于 NGINX Plus的 NGINX Ingress Controller 版本的有效许可证。 您可以申请30 天免费试用,立即开始使用许可证。 欲了解更多信息,请参阅我们的文档
  • Okta 开发者账户– 要将 Okta 配置为您的 IdP,请先注册一个开发者账户。 或者,下载Okta 命令行界面(CLI) 并运行okta register命令来注册一个新帐户。 在撰写本文时,Okta CLI 处于测试阶段,不建议用于生产使用。

预配置 IdP

云服务必须知道在哪里检索和验证用户身份,这就是 IdP 的必要性所在。 IdP 安全地管理和存储数字身份,并确保攻击者无法窃取身份来冒充用户。

在本节中,我们使用 Okta CLI 将 Okta 预先配置为 IdP,创建 Okta 所谓的应用程序集成

  1. 运行okta login命令以使用您的 Okta 开发者账户对 Okta CLI 进行身份验证。 在提示符下输入您的 Okta 域和API 令牌

    $ okta login Okta Org URL: https://你的 okta 域名Okta API 令牌:你的 api 令牌
    
  2. 创建应用程序集成:

    $ okta apps create --app-name=mywebapp --redirect-uri=http[s]:// ingress-controller-hostname /_codexch
    

    在哪里

    • --app-name定义应用名称(此处为mywebapp
    • --redirect-uri定义登录重定向到的 URI(此处为ingress-controller-hostname /_codexch
  3. 根据提示指定应用类型,首先使用1(代表一个 Web应用)然后5(代表除列出的框架之外的其他框架)。

    应用类型
    (Okta CLI 仅支持部分应用类型和属性):
    > 1: 网络
    > 2: 单页应用程序
    > 3: 原生应用(移动)
    > 4: 服务(机器对机器)
    输入您的选择 [Web]: 1
    应用类型
    > 1: Okta Spring Boot Starter
    > 2: Spring Boot
    > 3: JHipster
    > 4: Quarkus
    > 5: 其他
    输入您的选择[其他]: 5
    配置新的 OIDC应用,几乎完成:
    创建OIDC应用,客户端ID: 0oa1mi...OrfQAg5d7
    

配置 NGINX 入口控制器

配置基于NGINX Plus版本的NGINX Ingress Controller作为对用户进行认证的中继方。

定义客户端凭证机密

出于安全原因,不支持在 OIDC 策略对象中对客户端机密进行硬编码。 相反,我们创建一个 Kubernetes Secret,其数据包含客户端机密的 base64 编码值。

api版本: v1 种类: 机密元数据:名称:oidc-secret 类型:nginx.org/oidc 数据:客户端机密:客户端机密的 base64 编码值 

然后应用包含 Secret 的 YAML 文件(此处为client-secret.yaml ):

$ kubectl apply –f 客户端机密.yaml

获取身份验证端点

使用OAuth 2.0OpenID Connect API获取有关 Okta 在其授权服务器上公开的端点的信息。

在本地机器上运行以下命令以输出有关 Okta 端点的信息。 请注意示例输出中显示的authorization_endpointtoken_endpointjwks_uri的值。 您将在下一节中使用它们。

$ curl -i https://你的 okta 域名/.well-known/openid-configuration { “authorization_endpoint”:“https://你的 okta 域名/oauth2/v1/authorize”,... “jwks_uri”:“https://你的 okta 域名/oauth2/v1/keys”,... “token_endpoint”:“https://你的 okta 域名/oauth2/v1/token”,... }

定义 NGINX Ingress OIDC 策略

NGINX Ingress Controller 1.10.0 中添加了对基于 OIDC 的身份验证的支持。 有关详细信息,请阅读我们博客上的使用 OpenID Connect 和 NGINX Ingress Controller 进行简单且强大的单点登录

NGINX Ingress Controller 的 OIDC 身份验证实现使用Policy对象,这是一个 Kubernetes自定义资源,它在 NGINX Ingress Controller 中定义 OIDC 策略。

  1. 将上一节中获取的信息插入Policy对象的authEndpointtokenEndpointjwksURI字段中。

    api版本:k8s.nginx.org/v1 种类: 策略元数据:名称:oidc-policy 规范:oidc:clientID: client-id clientSecret:oidc-secret authEndpoint:https:// your-okta-domain /oauth2/v1/authorize tokenEndpoint:https:// your-okta-domain /oauth2/v1/token jwksURI:https:// your-okta-domain /oauth2/v1/keys
    
  2. 应用策略(此处在oidc.yaml中定义):

    $ kubectl 应用-f oidc.yaml
    
  3. (可选)检查策略的有效性:

    $ kubectl 获取策略名称 状态 年龄 oidc-policy 有效期 2 个月
    

定义 VirtualServer 对象

VirtualServer 和 VirtualServerRoute 是NGINX Ingress 资源,它们提供将传入流量路由到 Kubernetes 集群中的后端应用的规则。 要使 OIDC 策略生效,必须在 VirtualServer 或 VirtualServerRoute 资源中引用它。

  1. /路径前缀下引用 OIDC 策略,以便在请求代理到app-server-payload服务之前对请求与前缀匹配的路径的用户进行身份验证。

    api版本:k8s.nginx.org/v1
    种类: 虚拟服务器
    元数据:
    名称:app-ingress
    规格:
    主机:unit-demo.linkpc.net
    上游:
    -名称:app-server-payload
    服务:app-server-svc
    端口: 80
    路线:
    - 路径:/
    政策:
    - 名称:oidc-policy
    操作:
    代理:
    上游:app-server-payload
    
  2. 应用 VirtualServer 资源(此处在app-virtual-server.yaml中定义):

    $ kubectl apply -f app-virtual-server.yaml
    
  3. (选修的。) 验证资源的有效性:

    $ kubectl get vs NAME STATE HOST IP PORTS AGE app-ingress Valid unit-demo.linkpc.net 2m
    

测试环境

要测试 OIDC Okta 集成是否正常工作,请在浏览器的地址栏中输入 NGINX Ingress Controller 的主机名。 您将被重定向到 Okta 登录门户,您可以在其中输入您的 Okta 开发者帐户的凭据以访问后端应用。

一旦成功验证,您就可以访问app-server-payload上游服务。

将用户添加到application

大多数情况下,您组织中的多个用户需要访问您的应用。 在 Okta 管理控制台的目录类别下的人员页面上添加每个用户。

为多个应用程序创建 SSO 集成

我们通过配置 SSO 并使用 Okta 作为 IdP 并以 NGINX Ingress Controller 作为中继方,从一个应用中卸载了身份验证过程。 实际上,您可能希望让用户使用一组凭据访问许多应用。 您可能还希望灵活地改变用户可以访问的应用。 您可以通过重复以上部分中的说明来执行此操作:

在下图所示的示例中,有两个子域unit-demo.marketing.netunit-demo.engineering.net ,它们解析为 NGINX Ingress Controller 的外部 IP 地址。 NGINX Ingress Controller 根据子域将请求路由到营销应用程序或工程应用程序。 要授予用户访问权限,请在 Okta GUI 的“分配”选项卡上将用户与每个适当的应用关联。 然后,Okta 向经过身份验证的用户授予一个短期会话 cookie,以访问这些应用。

使用 NGINX Ingress Controller 和 Okta 作为 IdP 进行单点登录的多个应用集成拓扑图

结论

通过在 Kubernetes 中使用 NGINX Ingress Controller 作为中继方、使用 Okta 作为 IdP 实现基于 OIDC 的 SSO,您可以减轻开发人员的身份验证和授权负担,让他们可以专注于优化应用程序中的业务逻辑。 要开始使用基于 NGINX Plus 的NGINX Ingress Controller,请立即申请30 天免费试用联系我们讨论您的用例


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”