用Apache APISIX和OpenID Connect在网关处集中认证

795 阅读9分钟

Apache APISIX是一个动态、实时、高性能的API网关,提供丰富的流量管理。该项目提供了负载平衡、动态上游、金丝雀发布、断路、认证、可观察性和许多有用的插件。此外,该网关还支持动态插件变化以及热插拔。Apache APISIX的OpenID Connect插件允许用户通过OpenID Connect用集中式身份认证模式取代传统的认证模式。

注意:这篇文章最初出现在Apache APISIX的博客

什么是身份认证

身份认证通过特定的方式来验证用户的身份。我们从身份提供者(IdP)那里获得详细的用户元数据,以确定一个用户是否可以访问特定的资源。

身份认证模式

身份认证主要有两类:传统模式集中模式

传统认证模式

在传统认证模式下,每个应用服务都需要单独支持认证,比如在用户没有登录的情况下访问登录界面。该接口返回一个301 跳转页面。所有的应用服务都需要开发逻辑来维护会话,并与身份提供者交互认证。

你可以在下图中看到传统认证的流程。

首先,用户发起请求,然后网关接收请求并转发给相应的应用服务,最后,应用服务与身份提供者交互,完成授权。

集中式身份认证模式

与传统的认证方式不同,集中式身份认证模式将用户认证从应用服务中移除。以Apache APISIX为例,你可以在下图中看到集中式身份认证的过程。

首先,用户发起请求,然后网关本身负责用户认证过程,与身份提供者互动并向他们发送授权请求。身份提供者返回用户身份信息(用户信息)。在网关识别用户后,它将用户身份信息(用户信息)以请求头的形式转发给服务。

与传统的认证模式相比,集中式身份认证模式有以下优点:

  1. 集中认证模式简化了应用开发过程,避免了为每个应用重复开发认证代码,从而减少了开发应用的工作量和维护成本。
  2. 集中认证模式提高了业务安全性。在网关层面,它可以及时拦截未经认证的请求,保护后端应用。

什么是OpenID Connect

OpenID Connect(OIDC)是一种集中的身份认证模式。使用OpenID Connect的好处是,用户只需要在一个OpenID Connect身份提供者的网站上注册和登录,并使用一个账户的密码信息来访问不同的应用程序。Okta是一个常见的OpenID Connect身份提供者,而Apache APISIX OpenID Connect插件支持OpenID。 因此,该插件可以用集中式身份认证取代传统认证模式。 在这种情况下,我们使用Okta。

OpenID认证过程

  1. APISIX向身份提供者发起一个认证请求。
  2. 用户登录并在身份提供者上进行认证。
  3. 身份提供者将授权码返回给APISIX。
  4. APISIX用从请求参数中提取的代码请求身份提供者。
  5. 身份提供者向APISIX发送一个带有ID令牌和访问令牌的答复信息。
  6. APISIX将访问令牌发送到身份提供者的用户端点进行认证。
  7. 通过认证后,用户端点向APISIX发送用户信息以完成认证。

如何使用Apache APISIX OpenID连接插件配置Okta认证

使用Apache APISIX OpenID Connect插件配置Okta认证是一个三步走的过程,它允许你从传统认证切换到集中式身份认证模式。下面的章节描述了使用Apache APISIX的OpenID Connect插件配置Okta认证的步骤。

前提条件

准备好一个Okta账户供使用。

步骤1:配置Okta

  1. 登录您的Okta账户,点击创建应用程序集成,创建一个Okta应用程序。

  2. 在登录方式中选择OIDC-OpenID Connect,在应用类型中选择Web Application

  3. 设置登录和注销的重定向URL。登录重定向URI是用户在成功登录后可以进入的链接,而注销重定向URI是用户在成功注销后可以进入的链接。在这个例子中,我们把登录和注销的重定向URI都设置为http://127.0.0.1:9080/

  4. 完成设置后,单击 "保存"以保存更改。

  5. 访问应用程序的常规页面,获得以下配置,这是配置Apache APISIX OpenID Connect所需要的。

  • 客户端ID。OAuth客户端ID,即应用程序的ID,它对应于下面的client_id{YOUR_CLIENT_ID}
  • 客户端密码:OAuth客户端密码,应用程序的密钥,对应于下面的client_secret{YOUR_CLIENT_SECRET}
  • Okta域名。应用程序使用的域名,对应于下面的{YOUR_ISSUER}

步骤2:安装Apache APISIX

安装依赖项

Apache APISIX运行环境需要对NGINX和etcd的依赖。

在安装Apache APISIX之前,请根据你所使用的操作系统来安装依赖项。我们提供了CentOS7、Fedora 31和32、Ubuntu 16.04和18.04、Debian 9和10以及macOS的依赖项安装说明。更多细节请参考安装依赖项

通过RPM包安装(CentOS7)

这种安装方法适用于CentOS 7;请运行以下命令来安装Apache APISIX:

sudo yum install -y https://github.com/apache/apisix/releases/download/2.7/apisix-2.7-0.x86_64.rpm

通过源码发布安装

  1. 创建一个名为apisix-2.7 的目录:

     mkdir apisix-2.7
    
  2. 下载Apache APISIX Release源码包:

     wget https://downloads.apache.org/apisix/2.7/apache-apisix-2.7-src.tgz
    

    你也可以从Apache APISIX网站下载Apache APISIX发布源码包。Apache APISIX官方网站--下载页面还提供了Apache APISIX、APISIX Dashboard和APISIX Ingress Controller的源代码包。

  3. 解压Apache APISIX Release源码包:

     tar zxvf apache-apisix-2.7-src.tgz -C apisix-2.7
    
  4. 安装与运行时间相关的Lua库:

     # Switch to the apisix-2.7 directory
     cd apisix-2.7
     # Create dependencies
     make deps
    

初始化依赖关系

运行以下命令来初始化NGINX配置文件和etcd:

# initialize NGINX config file and etcd
make init

第3步:启动Apache APISIX并配置相应的路由

  1. 运行下面的命令来启动Apache APISIX:

     apisix start
    
  2. 创建一个路由并配置OpenID Connect插件。下面的代码示例通过Apache APISIX Admin API创建了一个路由,将上游路径设置为httpbin.org ,这是一个用于接收和响应请求的简单后端服务。下面将使用httpbin.org 的获取页面。请参考 httpbin get获取更多信息。关于具体的配置项目,请参考Apache APISIX OpenID Connect Plugin

OpenID Connect的配置字段列在下面:

字段默认值说明
client_id""OAuth客户端ID。
client_secret""OAuth客户端密码。
discovery""身份提供者的服务发现端点。
scopeopenid要访问的资源的范围。
relmapisix指定WWW-Authenticate响应头的认证信息。
bearer_onlyfalse是否检查请求头中的令牌。
logout_path/logout注销URI。
redirect_urirequest_uri身份提供者重定向回的URI,默认为请求地址。
timeout3请求超时时间,单位定义为秒。
ssl_verify错误验证身份提供者的SSL证书。
introspection_endpoint""身份提供者的令牌认证端点的URL,如果留空,将从发现、响应中提取。
introspection_endpoint_auth_methodclient_secret_basic用于令牌反省的认证方法的名称。
public_key""认证令牌的公钥。
token_signing_alg_values_expected""认证令牌的算法。
set_access_token_headertrue是否在请求头中携带访问令牌。
access_token_in_authorization_headerfalse是否将访问令牌放在授权头中。当此值设置为true时,访问令牌被放在授权头中,当设置为false时,则放在X-Access-Token 头中。
set_id_token_headertrue是否在X-ID-Token 请求头中携带ID令牌。
set_userinfo_headertrue是否在X-Userinfo 请求头中携带用户信息。
curl  -XPOST 127.0.0.1:9080/apisix/admin/routes \
  -H "X-Api-Key: edd1c9f034335f136f87ad84b625c8f1" -d '{
    "uri":"/*",
    "plugins":{
        "openid-connect":{
            "client_id":"{YOUR_CLIENT_ID}",
            "client_secret":"{YOUR_CLIENT_SECRET}",
            "discovery":"https://{YOUR_ISSUER}/.well-known/openid-configuration",
            "scope":"openid profile",
            "bearer_only":false,
            "realm":"master",
            "introspection_endpoint_auth_method":"client_secret_post",
            "redirect_uri":"http://127.0.0.1:9080/"
        }
    },
    "upstream":{
        "type":"roundrobin",
        "nodes":{
            "httpbin.org:80":1
        }
    }
}'

第四步:访问Apache APISIX

  1. 访问http://127.0.0.1:9080/get ,页面被重定向到Okta登录页面,因为OpenID连接插件已经启用。

  2. 输入用户的Okta账户的用户名和密码,然后点击Sign In登录到Okta账户。

  3. 登录成功后,你可以访问httpbin.org中的get页面。httpbin.org/get 页面将返回所请求的数据,其内容如下:X-Access-Token,X-Id-Token, 和X-Userinfo

  "X-Access-Token": "******Y0RPcXRtc0FtWWVuX2JQaFo1ZVBvSlBNdlFHejN1dXY5elV3IiwiYWxnIjoiUlMyNTYifQ.***TVER3QUlPbWZYSVRzWHRxRWh2QUtQMWRzVDVGZHZnZzAiLCJpc3MiOiJodHRwczovL3FxdGVzdG1hbi5va3RhLmNvbSIsImF1ZCI6Imh0dHBzOi8vcXF0ZXN0bWFuLm9rdGEuY29tIiwic3ViIjoiMjgzMDE4Nzk5QHFxLmNvbSIsImlhdCI6MTYyODEyNjIyNSwiZXhwIjoxNjI4MTI5ODI1LCJjaWQiOiIwb2ExMWc4ZDg3TzBGQ0dYZzY5NiIsInVpZCI6IjAwdWEwNWVjZEZmV0tMS3VvNjk1Iiwic2NwIjpbIm9wZW5pZCIsInByb2Zpb***.****iBshIcJhy8QNvzAFD0fV4gh7OAdTXFMu5k0hk0JeIU6Tfg_Mh-josfap38nxRN5hSWAvWSk8VNxokWTf1qlaRbypJrKI4ntadl1PrvG-HgUSFD0JpyqSQcv10TzVeSgBfOVD-czprG2Azhck-SvcjCNDV-qc3P9KoPQz0SRFX0wuAHWUbj1FRBq79YnoJfjkJKUHz3uu7qpTK89mxco8iyuIwB8fAxPMoXjIuU6-6Bw8kfZ4S2FFg3GeFtN-vE9bE5vFbP-JFQuwFLZNgqI0XO2S7l7Moa4mWm51r2fmV7p7rdpoNXYNerXOeZIYysQwe2_L****",
  "X-Id-Token": "******aTdDRDJnczF5RnlXMUtPZUtuSUpQdyIsImFtciI6WyJwd2QiXSwic3ViIjoiMDB1YTA1ZWNkRmZXS0xLdW82OTUiLCJpc3MiOiJodHRwczpcL1wvcXF0ZXN0bWFuLm9rdGEuY29tIiwiYXVkIjoiMG9hMTFnOGQ4N08wRkNHWGc2OTYiLCJuYW1lIjoiUGV0ZXIgWmh1IiwianRpIjoiSUQuNGdvZWo4OGUyX2RuWUI1VmFMeUt2djNTdVJTQWhGNS0tM2l3Z0p5TTcxTSIsInZlciI6MSwicHJlZmVycmVkX3VzZXJuYW1lIjoiMjgzMDE4Nzk5QHFxLmNvbSIsImV4cCI6MTYyODEyOTgyNSwiaWRwIjoiMDBvYTA1OTFndHAzMDhFbm02OTUiLCJub25jZSI6ImY3MjhkZDMxMWRjNGY3MTI4YzlmNjViOGYzYjJkMDgyIiwiaWF0IjoxNjI4MTI2MjI1LCJhdXRoX3RpbWUi*****",
  "X-Userinfo": "*****lfbmFtZSI6IlpodSIsImxvY2FsZSI6ImVuLVVTIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiMjgzMDE4Nzk5QHFxLmNvbSIsInVwZGF0ZWRfYXQiOjE2MjgwNzA1ODEsInpvbmVpbmZvIjoiQW1lcmljYVwvTG9zX0FuZ2VsZXMiLCJzdWIiOiIwMHVhMDVlY2RGZldLTEt1bzY5NSIsImdpdmVuX25hbWUiOiJQZXRlciIsIm5hbWUiOiJQZXRl****"

X-Access-Token。Apache APISIX将从用户提供者那里获得的访问令牌放入X-Access-Token 请求头,可以选择通过插件配置中的access_token_in_authorization_header 授权请求头。

X-Id-Token。Apache APISIX将通过base64编码从用户提供者那里获得的Id令牌放入X-Id-Token 请求头,你可以通过插件配置中的set_id_token_header ,选择是否启用这个功能,默认是启用。

X-Userinfo。Apache APISIX会从用户提供者那里获取用户信息,并通过Base64编码后放入X-Userinfo ,你可以通过插件配置中的set_userinfo_header ,选择是否启用这个功能,默认设置为开启。

正如你所看到的,Apache APISIX将携带X-Access-Token,X-Id-Token, 和X-Userinfo 请求头到上游。上游可以解析这些头信息以获得用户ID信息和用户元数据。

我们已经展示了从Okta直接到Apache APISIX网关建立集中身份认证的过程。注册一个免费的Okta开发者账户就可以轻松开始了。我们的方法减少了开发者的开销,实现了安全和精简的体验。

关于Okta

Okta是一个可定制的、安全的、可直接使用的解决方案,为您的应用程序添加认证和授权服务。在您的应用程序中直接获得可扩展的认证,而不需要自己编写代码所带来的开发开销、安全风险和维护。您可以将任何语言或任何堆栈的任何应用程序连接到Okta,并定义您希望您的用户如何登录。每次用户尝试认证时,Okta都会验证他们的身份,并将所需信息发回给您的应用程序。