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"}