Kong多认证插件

Kong支持 同时启用多个身份认证 (Auth)插件,允许客户端使用不同的身份验证方法来访问指定的服务 (Services)或路由(Routes)

创建一个消费者

创建消费者

创建消费者 devops

1
2
3
4
5
6
7
$ curl -X POST --url http://localhost:8001/consumers/ --data "username=devops"
{
"custom_id":null,
"created_at":1566380171,
"username":"devops",
"id":"a1b6c169-f6e3-482e-a477-2d09d14dce8b"
}
生成key-auth认证秘钥

为消费者 devops生成秘钥凭证,可以指定key值,也可以让插件自动生成key值,建议插件自动生成

1
2
3
4
5
6
7
8
9
$ curl -X POST --url http://localhost:8001/consumers/devops/key-auth/
{
"key": "OLCgYhkbjfZueFBQ7qe3nOYuWiUdOiiN",
"created_at": 1566382283,
"consumer": {
"id": "a1b6c169-f6e3-482e-a477-2d09d14dce8b"
},
"id": "e9dafd25-5e18-4ec1-a41d-b4fc9ea20208"
}

可以通过接口/key-auths查看所有消费者的秘钥,通过/consumers/{consumer}/key-auth接口查看指定消费者的秘钥。

生成JWT凭证
1
2
3
4
5
6
7
8
9
10
11
12
13
$ curl -X POST http://localhost:8001/consumers/devops/jwt \
> -H "Content-Type: application/x-www-form-urlencoded"
{
"rsa_public_key": null,
"created_at": 1566382780,
"consumer": {
"id": "a1b6c169-f6e3-482e-a477-2d09d14dce8b"
},
"id": "c0296bae-b9bd-4835-b433-95dff237bb4b",
"algorithm": "HS256",
"secret": "EGUUr9v99DMGwIk9SpBxvigjzFi5GsBZ",
"key": "GiweuLOEAwSO9cxkibug7MaBfdJE4NPB"
}

可以通过/jwts接口查看所有消费者的jwt凭证,通过/consumers/{consumer}/jwt接口查看指定消费者的凭证。

启用多个认证插件

插件可以应用于RouteServiceGlobal,这里以Global为例。并同时启动key-authjwt认证插件。

启用key-auth认证插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ curl -X POST --url http://localhost:8001/plugins/ --data "name=key-auth"
{
"created_at": 1566381363,
"config": {
"key_names": [
"apikey"
],
"run_on_preflight": true,
"anonymous": null,
"hide_credentials": false,
"key_in_body": false
},
"id": "947db416-1f3a-4a54-a5ff-75b6a55206d7",
"service": null,
"enabled": true,
"run_on": "first",
"consumer": null,
"route": null,
"name": "key-auth"
}
启用jwt认证插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ curl -X POST --url http://localhost:8001/plugins/ --data "name=jwt"
{
"created_at": 1566383438,
"config": {
"secret_is_base64": false,
"key_claim_name": "iss",
"cookie_names": [],
"maximum_expiration": 0,
"claims_to_verify": null,
"anonymous": null,
"run_on_preflight": true,
"uri_param_names": [
"jwt"
]
},
"id": "fc54429b-73cd-4215-8f4d-35a21c6a389e",
"service": null,
"enabled": true,
"run_on": "first",
"consumer": null,
"route": null,
"name": "jwt"
}

多重认证-AND

Kong启用多个认证插件后,默认的执行逻辑是 AND。例如启用了两个认证插件key-authjwt,那么每次的请求必须提供这两个插件的认证信息,必须通过所有认证插件的认证,才会将下游的请求转发到上游。

使用key-auth 认证方式,请求状态401,返回jwt插件的未认证信息提示{"message":"Unauthorized"}

1
2
3
4
5
6
$ curl -i -X GET --url http://192.168.1.100:8000/api/test/ \
-H "apikey: OLCgYhkbjfZueFBQ7qe3nOYuWiUdOiiN"
HTTP/1.1 401 Unauthorized
... ... ...

{"message":"Unauthorized"}

使用 jwt 认证方式,请求状态401,返回key-auth插件的未认证信息提示{"message":"No API key found in request"}

1
2
3
4
5
6
$ curl -i -X GET --url http://192.168.1.100:8000/api/test/ \
> -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJHaXdldUxPRUF3U085Y3hraWJ1ZzdNYUJmZEpFNE5QQiJ9.UjxuXIu4yI6VyZeoDIfrMLpqggKE4n63o_IQMbygPFA"
HTTP/1.1 401 Unauthorized
... ... ...

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

同时使用key-authjwt 认证方式,成功返回请求数据,请求状态200

1
2
3
4
5
$ curl -i -X GET --url http://192.168.1.100:8000/api/test/ \
> -H "apikey: OLCgYhkbjfZueFBQ7qe3nOYuWiUdOiiN" \
> -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJHaXdldUxPRUF3U085Y3hraWJ1ZzdNYUJmZEpFNE5QQiJ9.UjxuXIu4yI6VyZeoDIfrMLpqggKE4n63o_IQMbygPFA"
HTTP/1.1 200 OK
... ... ...

多种认证-OR

Kong启用多个认证插件后,默认的执行逻辑是 AND,当认证插件都启用匿名访问后,执行逻辑将会变为 OR

在不启用匿名访问的时候,auth插件将始终执行身份验证,如果未经过验证,则返回40x响应。当启用匿名访问后auth插件只会在未经过身份验证的情况下执行身份验证,如果身份验证失败,它不会返回40x响应,而是将匿名使用者设置为有效的消费者,那么当调用多个auth插件时,就会导致 OR + 匿名访问的逻辑。如果配合request-termination plugin插件拦截匿名访问的请求,禁止匿名访问,就可以达到多种认证 OR的效果。

创建匿名消费者
1
2
3
4
5
6
7
8
$ curl -X POST --url http://localhost:8001/consumers/ \
> --data "username=anonymous"
{
"custom_id": null,
"created_at": 1566388995,
"username": "anonymous",
"id": "958e85d7-e39d-4d2c-b8a9-888e25dbeed5"
}
启用匿名访问

key-auth插件启用匿名访问,插件id947db416-1f3a-4a54-a5ff-75b6a55206d7,匿名用户id958e85d7-e39d-4d2c-b8a9-888e25dbeed5

1
2
$ curl -X PATCH --url http://localhost:8001/plugins/947db416-1f3a-4a54-a5ff-75b6a55206d7/ \
> --data "config.anonymous=958e85d7-e39d-4d2c-b8a9-888e25dbeed5"

jwt插件启用匿名访问,插件idfc54429b-73cd-4215-8f4d-35a21c6a389e,匿名用户id958e85d7-e39d-4d2c-b8a9-888e25dbeed5

1
2
$ curl -X PATCH --url http://localhost:8001/plugins/fc54429b-73cd-4215-8f4d-35a21c6a389e/ \
> --data "config.anonymous=958e85d7-e39d-4d2c-b8a9-888e25dbeed5"

启用匿名访问后,请求将不需要认证

1
2
3
$ curl -i -X GET --url http://192.168.1.100:8000/api/test/
HTTP/1.1 200 OK
... ... ...
拦截匿名请求

启用request-termination插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ curl -X POST http://localhost:8001/plugins/ \
> --data "name=request-termination" \
> --data "config.status_code=401" \
> --data "config.content_type=application/json; charset=utf-8" \
> --data "config.body={\"message\": \"Authentication required\"}"

{
"created_at": 1566391156,
"config": {
"status_code": 401,
"content_type": "application/json; charset=utf-8",
"body": "{\"message\": \"Authentication required\"}",
"message": null
},
"id": "e5ff19cf-006d-4fcd-ae00-5837bc5d6938",
"service": null,
"enabled": true,
"run_on": "first",
"consumer": null,
"route": null,
"name": "request-termination"
}

匿名消费者anonymous启用该拦截插件,插件ide5ff19cf-006d-4fcd-ae00-5837bc5d6938,匿名消费者id958e85d7-e39d-4d2c-b8a9-888e25dbeed5

1
2
$ curl -X PATCH http://localhost:8001/plugins/e5ff19cf-006d-4fcd-ae00-5837bc5d6938/ \
--data "consumer.id=958e85d7-e39d-4d2c-b8a9-888e25dbeed5"

此时匿名请求已被拦截

1
2
3
4
5
$ curl -i -X GET --url http://192.168.1.100:8000/api/test/
HTTP/1.1 401 Unauthorized
... ... ...

{"message": "Authentication required"}

但是只要通过任一种验证,即可成功请求数据

1
2
3
4
5
6
7
8
9
10
# key-auth
$ curl -i -X GET http://192.168.1.100:8000/api/test/ \
> -H "apikey: OLCgYhkbjfZueFBQ7qe3nOYuWiUdOiiN"
HTTP/1.1 200 OK
... ... ...
# jwt
$ curl -i -X GET http://192.168.1.100:8000/api/test/ \
> -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJHaXdldUxPRUF3U085Y3hraWJ1ZzdNYUJmZEpFNE5QQiJ9.UjxuXIu4yI6VyZeoDIfrMLpqggKE4n63o_IQMbygPFA"
HTTP/1.1 200 OK
... ...

此时的多认证插件(Auth)执行逻辑是 OR

----------------本文结束 感谢阅读----------------