You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by me...@apache.org on 2020/08/06 09:07:16 UTC
[apisix] branch master updated: feat: Support SSL verify option to
Authz Keycloak plugin (#1924)
This is an automated email from the ASF dual-hosted git repository.
membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 712a23f feat: Support SSL verify option to Authz Keycloak plugin (#1924)
712a23f is described below
commit 712a23f9b02e46720ff87be974d67d5ff9be173e
Author: Nirojan Selvanathan <ss...@gmail.com>
AuthorDate: Thu Aug 6 11:07:07 2020 +0200
feat: Support SSL verify option to Authz Keycloak plugin (#1924)
Fix #1855
---
.travis/linux_openresty_runner.sh | 2 +-
.travis/linux_tengine_runner.sh | 2 +-
apisix/plugins/authz-keycloak.lua | 3 +-
doc/plugins/authz-keycloak.md | 1 +
t/plugin/authz-keycloak.t | 194 ++++++++++++++++++++++++++++++++++++++
5 files changed, 199 insertions(+), 3 deletions(-)
diff --git a/.travis/linux_openresty_runner.sh b/.travis/linux_openresty_runner.sh
index d5922c6..caba1d1 100755
--- a/.travis/linux_openresty_runner.sh
+++ b/.travis/linux_openresty_runner.sh
@@ -39,7 +39,7 @@ before_install() {
docker run --rm -itd -p 6379:6379 --name apisix_redis redis:3.0-alpine
docker run --rm -itd -e HTTP_PORT=8888 -e HTTPS_PORT=9999 -p 8888:8888 -p 9999:9999 mendhak/http-https-echo
# Runs Keycloak version 10.0.2 with inbuilt policies for unit tests
- docker run --rm -itd -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=123456 -p 8090:8080 sshniro/keycloak-apisix
+ docker run --rm -itd -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=123456 -p 8090:8080 -p 8443:8443 sshniro/keycloak-apisix
# spin up kafka cluster for tests (1 zookeper and 1 kafka instance)
docker pull bitnami/zookeeper:3.6.0
docker pull bitnami/kafka:latest
diff --git a/.travis/linux_tengine_runner.sh b/.travis/linux_tengine_runner.sh
index e5e81e9..ec73c16 100755
--- a/.travis/linux_tengine_runner.sh
+++ b/.travis/linux_tengine_runner.sh
@@ -40,7 +40,7 @@ before_install() {
docker run --rm -itd -p 6379:6379 --name apisix_redis redis:3.0-alpine
docker run --rm -itd -e HTTP_PORT=8888 -e HTTPS_PORT=9999 -p 8888:8888 -p 9999:9999 mendhak/http-https-echo
# Runs Keycloak version 10.0.2 with inbuilt policies for unit tests
- docker run --rm -itd -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=123456 -p 8090:8080 sshniro/keycloak-apisix
+ docker run --rm -itd -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=123456 -p 8090:8080 -p 8443:8443 sshniro/keycloak-apisix
# spin up kafka cluster for tests (1 zookeper and 1 kafka instance)
docker pull bitnami/zookeeper:3.6.0
docker pull bitnami/kafka:latest
diff --git a/apisix/plugins/authz-keycloak.lua b/apisix/plugins/authz-keycloak.lua
index 2704f4e..66dc1de 100644
--- a/apisix/plugins/authz-keycloak.lua
+++ b/apisix/plugins/authz-keycloak.lua
@@ -51,7 +51,7 @@ local schema = {
keepalive = {type = "boolean", default = true},
keepalive_timeout = {type = "integer", minimum = 1000, default = 60000},
keepalive_pool = {type = "integer", minimum = 1, default = 5},
-
+ ssl_verify = {type = "boolean", default = true},
},
required = {"token_endpoint"}
}
@@ -107,6 +107,7 @@ local function evaluate_permissions(conf, token)
response_mode = "decision",
permission = conf.permissions
}),
+ ssl_verify = conf.ssl_verify,
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Authorization"] = token
diff --git a/doc/plugins/authz-keycloak.md b/doc/plugins/authz-keycloak.md
index 43cbd09..7fb6a13 100644
--- a/doc/plugins/authz-keycloak.md
+++ b/doc/plugins/authz-keycloak.md
@@ -45,6 +45,7 @@ For more information on Keycloak, refer to [Keycloak Authorization Docs](https:/
| audience |optional |The client identifier of the resource server to which the client is seeking access. This parameter is mandatory in case the permission parameter is defined.|
| permissions |optional |This parameter is optional. A string representing a set of one or more resources and scopes the client is seeking access. The format of the string must be: `RESOURCE_ID#SCOPE_ID`.|
| timeout |optional |Timeout for the http connection with the Identity Server. Default is 3 seconds|
+| ssl_verify |optional |Verify SSL cert matches hostname|
| policy_enforcement_mode|required |Enforcing or Permissive.|
diff --git a/t/plugin/authz-keycloak.t b/t/plugin/authz-keycloak.t
index 00ebc0d..3ac3c4b 100644
--- a/t/plugin/authz-keycloak.t
+++ b/t/plugin/authz-keycloak.t
@@ -351,3 +351,197 @@ GET /t
true
--- error_log
{"error":"access_denied","error_description":"not_authorized"}
+
+
+
+=== TEST 9: Add htttps endpoint with ssl_verify true (default)
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "authz-keycloak": {
+ "token_endpoint": "https://127.0.0.1:8443/auth/realms/University/protocol/openid-connect/token",
+ "permissions": ["course_resource#delete"],
+ "audience": "course_management",
+ "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
+ "timeout": 3000
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1982": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello1"
+ }]],
+ [[{
+ "node": {
+ "value": {
+ "plugins": {
+ "authz-keycloak": {
+ "token_endpoint": "https://127.0.0.1:8443/auth/realms/University/protocol/openid-connect/token",
+ "permissions": ["course_resource#delete"],
+ "audience": "course_management",
+ "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
+ "timeout": 3000
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1982": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello1"
+ },
+ "key": "/apisix/routes/1"
+ },
+ "action": "set"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 10: TEST with fake token and https endpoint
+--- config
+ location /t {
+ content_by_lua_block {
+ local http = require "resty.http"
+ local httpc = http.new()
+ local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello1"
+ local res, err = httpc:request_uri(uri, {
+ method = "GET",
+ headers = {
+ ["Authorization"] = "Bearer " .. "fake access token",
+ }
+ })
+
+ if res.status == 200 then
+ ngx.say(true)
+ else
+ ngx.say(false)
+ end
+ }
+ }
+--- request
+GET /t
+--- response_body
+false
+--- error_log
+error while sending authz request to [127.0.0.1] port[8443] 18: self signed certificate
+
+
+
+=== TEST 11: Add htttps endpoint with ssl_verify false
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "authz-keycloak": {
+ "token_endpoint": "https://127.0.0.1:8443/auth/realms/University/protocol/openid-connect/token",
+ "permissions": ["course_resource#delete"],
+ "audience": "course_management",
+ "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
+ "timeout": 3000,
+ "ssl_verify": false
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1982": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello1"
+ }]],
+ [[{
+ "node": {
+ "value": {
+ "plugins": {
+ "authz-keycloak": {
+ "token_endpoint": "https://127.0.0.1:8443/auth/realms/University/protocol/openid-connect/token",
+ "permissions": ["course_resource#delete"],
+ "audience": "course_management",
+ "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
+ "timeout": 3000,
+ "ssl_verify": false
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1982": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello1"
+ },
+ "key": "/apisix/routes/1"
+ },
+ "action": "set"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 12: TEST for https based token verification with ssl_verify false
+--- config
+ location /t {
+ content_by_lua_block {
+ local http = require "resty.http"
+ local httpc = http.new()
+ local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello1"
+ local res, err = httpc:request_uri(uri, {
+ method = "GET",
+ headers = {
+ ["Authorization"] = "Bearer " .. "fake access token",
+ }
+ })
+
+ if res.status == 200 then
+ ngx.say(true)
+ else
+ ngx.say(false)
+ end
+ }
+ }
+--- request
+GET /t
+--- response_body
+false
+--- error_log
+status code: 401 msg: {"error":"HTTP 401 Unauthorized"}