跳转到主要内容

热门内容

今日:


总体:


最近浏览:


Chinese, Simplified

category

在这篇文章中,我们将很快描述不同的身份验证方法,概述Apache APISIX API网关的集中式身份验证的使用情况和优点,并将学习如何配置常见的身份验证插件,如基本、密钥和JWT,以保护您的服务。所以,让我们开始吧。

关于Apache APISIX


Apache APISIX是一个开源的API网关,它提供管理流量的服务,如速率限制、可观察性、日志记录、安全性、身份验证等。它还有许多内置插件,适合所有API和微服务。我们将在特定教程中重点介绍的是身份验证插件。目前,它已经可以与大量与身份验证相关的插件一起工作,正如您在插件中心页面上看到的那样。

API身份验证


API身份验证是为了证明或验证访问您的系统的人员的身份。这是一个使用软件协议来确保网络上的客户端在授予访问权限之前是他们声称的样子的过程。


有几种API身份验证方法,以下是我们在本教程中回顾的一些最流行的方法,而不深入讨论细节,因为我们的主要关注点是身份验证插件。如果你已经很熟悉它们,你可以跳过这个理论部分,直接跳到下面的插件实用教程部分:

  • HTTP基本认证
  • API密钥验证
  • OAuth/Auth2身份验证


HTTP基本认证


处理身份验证的最简单方法是使用HTTP,其中用户名和密码与每个API调用一起发送。您可以使用HTTP标头对用户名和密码进行编码,如下图所示:


API密钥验证


应用程序编程接口密钥(ApplicationProgrammingInterfaceKey,API密钥)技术为用户创建唯一的密钥,并将它们与每个请求一起传递。API生成一个密钥,该密钥是一个由数字和字母组成的长字符串,长度至少为30个字符,尽管没有设定标准长度。它通常与API授权头一起传递。


OAuth身份验证


开放授权(OAuth)是另一种广泛用于身份验证和授权的方法。在这种方法中,用户登录到系统中。然后,该系统将请求身份验证,通常以令牌的形式进行。然后,用户将此请求转发到身份验证服务器,该服务器将拒绝或允许此身份验证。从这里开始,令牌被提供给用户,然后再提供给请求者。然后,请求者可以在任何时候独立于用户来检查这样的令牌以进行验证,并且可以在严格限制有效范围和有效期的情况下随时间使用。

从传统认证模式到集中式认证模式


Apache APISIX可以用作集中式身份验证网关。例如,您有三个要公开的服务,左边的图表向我们展示了一种更常见的传统身份验证方法。每个应用程序服务模块都要开发一个单独的身份验证模块,用于支持一组身份验证过程处理。但是,当服务量增加时,很明显,这些模块的开发工作量是巨大且重复的。


对于上述场景,我们可以通过替换Apache APISIX网关中的这部分开发逻辑来实现整合并减少开发量。

如上图右侧所示,用户或应用方直接去请求Apache APISIX,然后Apache APISIX在识别和认证后将认证后的身份信息传递给上游应用服务。之后,上游应用服务可以从请求头中读取这些信息,然后处理后续的相关工作。

与身份提供者的沟通


我们可以发现APISIX作为身份验证处理程序的另一种高级用法。API网关通常是我们与IDP(身份提供者)进行所有交互的地方,用于这些上游服务。它单独与身份提供者交互,只需要知道如何处理身份验证逻辑流,并避免为每个应用程序重复开发身份验证代码。有各种IDP提供商,如Okta、Cognito、Azure Active Directory等。


集中认证的过程如图所示,首先由用户发起请求,然后由前端网关负责用户认证过程,与身份提供者接口,并向身份提供者发送授权请求。身份提供程序返回用户信息。网关完成用户标识后,以请求头的形式将用户标识信息转发给后端应用程序。

Apache APISIX插件教程


到目前为止,我们已经掌握了足够的理论知识,是时候使用Apache APISIX Auth插件了。然而,在Apache APISIX根据我们的需要工作之前,我们应该学习几个核心概念。如果您还不熟悉以下内容,可以通读文档。

  • 路由是Apache APISIX中最关键的概念;它指示APISIX如何将业务转发到正确的上游。
  • Upstream是从Apache APISIX的角度来看后端微服务的观点。
  • 插件是一种在APISIX端管理流量(身份验证、授权等)的机制。
     

预备知识

  • 已安装Docker和Docker Compose组件。
  • 用于API测试的curl命令。您还可以使用Postman等其他工具进行测试。


安装Apache APISIX


下载Apache APISIX的Docker镜像。

git clone https://github.com/apache/apisix-docker.git


将当前目录切换到apisix docker/example路径。

cd apisix-docker/example


运行docker compose命令来安装Apache APISIX。

docker-compose -p docker-apisix up -d


HTTP基本身份验证插件


Apache APISIX基本身份验证插件是一个与使用者对象一起工作的身份验证插件。在HTTP事务的上下文中,基本访问身份验证是一种在发出请求时提供用户名和密码的方法。

让我们为使用者启用基本的身份验证插件,并配置用户名和密码的值。

curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
   "username": "foo",
   "plugins": {
       "basic-auth": {
           "username": "example_username",
           "password": "your_strong_password"
       }
   }
}'


成功创建使用者后,您将在响应中获得以下JSON对象:

{
 "node": {
   "value": {
     "create_time": 1650866058,
     "username": "foo",
     "update_time": 1650866058,
     "plugins": {
       "basic-auth": {
         "password": "your_strong_password",
         "username": "example_username"
       }
     }
   },
   "key": "/apisix/consumers/foo"
 },
 "action": "set"
}


之后,我们需要添加一个Route,并允许基本身份验证通过在插件设置中指定请求来控制请求:

curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
   "methods": ["GET"],
   "uri": "/get",
   "plugins": {
       "basic-auth": {}
   },
   "upstream_id": "1"
}'


Apache APISIX服务器成功响应:

{
 "node": {
   "value": {
     "methods": [
       "GET"
     ],
     "upstream_id": "1",
     "uri": "/get",
     "update_time": 1650866398,
     "plugins": {
       "basic-auth": {
         "hide_credentials": false
       }
     },
     "status": 1,
     "create_time": 1648567195,
     "id": "1",
     "priority": 0
   },
   "key": "/apisix/routes/1"
 },
 "action": "set"
}


到目前为止,我们已经做好了准备,我们可以在下面测试不同的案例:

案例1:在没有授权详细信息的情况下请求/获取端点。
 

curl -i http://127.0.0.1:9080/get


正如我们预期的那样,您将在响应中收到HTTP 401错误:

{"message":"Missing authorization in request"}


情况2:当用户提供有效的用户名和密码时。
curl -i -uexample_username:your_strong_password http://127.0.0.1:9080/get


乌拉!现在,我们从上游得到了200 OK的响应,表明身份验证插件运行良好。

HTTP/1.1 200 OK


情况3:当我们使用错误的用户凭据访问上游时。
curl -i -uexample_username:wrong_password http://127.0.0.1:9080/get
正确,我们收到一个错误,说“密码不正确”

{"message":"Password is error"}
以上就是基本的auth-plugin设置。

API密钥身份验证插件


在上一节中,我们在APISIX基本身份验证插件的帮助下演示了一种类型的身份验证方法的可用性。现在让我们来看看另一个插件密钥验证

Apache APISIX密钥身份验证插件是一个身份验证插件,它应该与消费者一起工作。

将密钥验证(有时也称为API密钥)添加到服务或路由。然后,消费者将他们的密钥添加到查询字符串参数或标头中,以验证他们的请求。

要启用密钥验证插件,需要完成两个步骤:

步骤1:创建一个使用者对象,并设置插件密钥auth的属性。


curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
   "username": "example_username",
   "plugins": {
       "key-auth": {
           "key": "auth-one"
       }
   }
}'


APISIX的回复如下:

{
 "node": {
   "value": {
     "username": "example_username",
     "update_time": 1650822986,
     "plugins": {
       "key-auth": {
         "key": "auth-one"
       }
     },
     "create_time": 1650822986
   },
   "key": "/apisix/consumers/example_username"
 },
 "action": "set"
}

第二步:在我们启用密钥认证插件后,我们可以创建一个新的路由并应用密钥认证插件配置。为了简单起见,我们可以将密钥验证插件的JSON对象保留为空。


curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
   "methods": ["GET"],
   "uri": "/get",
   "plugins": {
       "key-auth": {}
   },
   "upstream_id": "1"
}'


默认情况下,APISIX在标头中将密钥名称设置为apiKey,您也可以通过添加密钥验证插件的配置来自定义默认标头

{
   "key-auth": {
       "header": "Authorization"
   }
}


您将从管理API终结点获得以下响应:

{
 "node": {
   "value": {
     "uri": "/get",
     "priority": 0,
     "status": 1,
     "plugins": {
       "key-auth": {
         "header": "apikey",
         "query": "apikey"
       }
     },
     "create_time": 1648567195,
     "update_time": 1650823379,
     "methods": [
       "GET"
     ],
     "upstream_id": "1",
     "id": "1"
   },
   "key": "/apisix/routes/1"
 },
 "action": "set"
}


现在,我们可以通过访问不带apiKey头的GET端点来测试我们的密钥验证插件。

curl http://127.0.0.2:9080/get


正如我们所预期的,它返回一个错误,401 HTTP状态代码:

{"message":"Missing API key found in request"}


或者,如果我们在头中指定apiKey,它应该以成功作为响应:

curl http://127.0.0.2:9080/get -H 'apikey: auth-one' -i


很好,现在为端点启用了API密钥身份验证。

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 326
Connection: keep-alive


另一种情况是用户试图使用错误的apiKey访问端点

curl http://127.0.0.2:9080/get -H 'apikey: wrong_api_key' -i


输出

{"message":"Invalid API key in request"}


JWT插件


JWT(JSON Web令牌)插件是API网关身份验证的另一个可靠选项。JWT简化了身份验证设置,处理了细节。请参阅JWT了解更多信息。

Apache APISIX JWT插件充当颁发者,还代表API验证令牌。这意味着开发人员不必添加任何代码来处理身份验证。

我们需要禁用之前启用的密钥身份验证插件才能使用另一个身份验证插件。可以通过仪表板或CLI禁用。


让我们将JWT插件应用于我们现有的API。我们使用JWT相关配置更新现有的Consumer插件配置:

curl http://127.0.0.1:9080/apisix/admin/consumers -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"username": "example_consumer",
"plugins": {
"jwt-auth": {
"key": "user-key",
"secret": "my-secret-key"
}
}
}'


回复如下:

{
 "node": {
   "key": "/apisix/consumers/example_consumer",
   "value": {
     "create_time": 1649158467,
     "username": "example_consumer",
     "update_time": 1649163154,
     "plugins": {
       "jwt-auth": {
         "base64_secret": false,
         "secret": "my-secret-key",
         "algorithm": "HS256",
         "key": "user-key",
         "exp": 86400
       }
     }
   }
 },
 "action": "set"
}


我们现在可以将jwt auth插件添加到我们之前创建的Route中:

curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"methods": ["GET"],
"uri": "/get",
"plugins": {
"jwt-auth": {}
},
"upstream_id": "1"
}'


回答

{
 "node": {
   "key": "/apisix/routes/1",
   "value": {
     "upstream_id": "1",
     "uri": "/get",
     "create_time": 1648567195,
     "status": 1,
     "id": "1",
     "plugins": {
       "jwt-auth": {}
     },
     "priority": 0,
     "methods": [
       "GET"
     ],
     "update_time": 1649163340
   }
 },
 "action": "set"
}


我们想验证设置是否与以前一样正确。

jwt-auth默认使用HS256算法。
如果使用RS256算法,则必须指定算法并配置公钥和私钥。
有关更多详细信息,请查看文档。

首先,您需要为签署令牌的API设置路由,该API将使用public-API插件。

curl http://127.0.0.1:9080/apisix/admin/routes/jas -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/apisix/plugin/jwt/sign",
"plugins": {
"public-api": {}
}
}'


回答

{
 "action": "set",
 "node": {
   "key": "/apisix/routes/jas",
   "value": {
     "status": 1,
     "priority": 0,
     "id": "jas",
     "update_time": 1649490287,
     "plugins": {
       "public-api": {}
     },
     "uri": "/apisix/plugin/jwt/sign",
     "create_time": 1649490287
   }
 }
}


然后,运行以下命令以生成新的JWT令牌:

curl http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key -i


Apache APISIX返回一个令牌:

HTTP/1.1 200 OK
Date: Tue, 05 Apr 2022 12:57:34 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Server: APISIX/2.12.1<GENERATED_TOKEN>


我们可以使用新生成的令牌来验证我们的下一个请求:

curl -i -X GET http://127.0.0.1:9080/get -H 'Authorization: <SET_GENERATED_TOKEN>'


使用令牌输出:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 454
Connection: keep-alive
Date: Tue, 05 Apr 2022 13:02:30 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/2.12.1


如果尝试在Header请求中不使用令牌访问同一个端点,则会收到HTTP错误_401未经授权:

curl -i -X GET http://127.0.0.1:9080/get


无标记输出:

{ "message": "Missing JWT token in request" }


有了JWT插件演示,我们的插件教程就结束了。

总结


我们已经在Apache APISIX的帮助下使用各种身份验证插件验证了尝试请求的客户端的身份。APISIX现在可以与各种插件函数合作进行新的改编,并且插件库相对丰富。

 

本文地址
最后修改
星期四, June 6, 2024 - 10:38
Article