You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by we...@apache.org on 2020/03/15 12:40:18 UTC

[incubator-apisix] branch master updated: feature: adding support to public key based introspection for OAuth plugin (#1266)

This is an automated email from the ASF dual-hosted git repository.

wenming pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new c1df18f  feature: adding support to public key based introspection for OAuth plugin (#1266)
c1df18f is described below

commit c1df18f769d181cbdb1cff27012e621fa418f5f6
Author: Nirojan Selvanathan <ss...@gmail.com>
AuthorDate: Sun Mar 15 13:40:10 2020 +0100

    feature: adding support to public key based introspection for OAuth plugin (#1266)
---
 doc/plugins/oauth.md                  | 39 +++++++++++++++++++++++++++++++++++
 lua/apisix/plugins/openid-connect.lua | 20 ++++++++++++++----
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/doc/plugins/oauth.md b/doc/plugins/oauth.md
index 3ecfeea..3b3f0e6 100644
--- a/doc/plugins/oauth.md
+++ b/doc/plugins/oauth.md
@@ -42,6 +42,8 @@ The OAuth 2 / Open ID Connect(OIDC) plugin provides authentication and introspec
 |ssl_verify     |optional       |default is `false`|
 |introspection_endpoint                 |optional       |URL of the token verification endpoint of the identity server|
 |introspection_endpoint_auth_method     |optional       |Authentication method name for token introspection |
+|public_key     |optional       |The public key to verify the token |
+|token_signing_alg_values_expected     |optional       |Algorithm used to sign the token |
 
 ### Token Introspection
 
@@ -87,6 +89,43 @@ The following command can be used to access the new route.
 curl -i -X GET http://127.0.0.1:9080/get -H "Host: httpbin.org" -H "Authorization: Bearer {replace_jwt_token}"
 ```
 
+#### Introspecting with public key
+
+You can also provide the public key of the JWT token to verify the token. In case if you have provided a public key and
+a token introspection endpoint, the public key workflow will be executed instead of verifying with the identity server.
+This method can be used if you want to reduce additional network calls and to speedup the process.
+
+The following configurations shows how to add a public key introspection to a route.
+
+```bash
+curl http://127.0.0.1:9080/apisix/admin/routes/5 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
+{
+  "uri": "/get",
+  "plugins": {
+    "proxy-rewrite": {
+      "scheme": "https"
+    },
+    "openid-connect": {
+      "client_id": "api_six_client_id",
+      "client_secret": "client_secret_code",
+      "discovery": "full_URL_of_the_discovery_endpoint",
+      "bearer_only": true,
+      "realm": "master",
+      "token_signing_alg_values_expected": "RS256",
+      "public_key" : "-----BEGIN CERTIFICATE-----
+        {public_key}
+        -----END CERTIFICATE-----"
+}
+  },
+  "upstream": {
+    "type": "roundrobin",
+    "nodes": {
+      "httpbin.org:443": 1
+    }
+  }
+}'
+```
+
 ## Troubleshooting
 
 Check/modify the DNS settings (`conf/config.yaml) if APISIX cannot resolve/connect to the identity provider.
diff --git a/lua/apisix/plugins/openid-connect.lua b/lua/apisix/plugins/openid-connect.lua
index 17a0538..6a93226 100644
--- a/lua/apisix/plugins/openid-connect.lua
+++ b/lua/apisix/plugins/openid-connect.lua
@@ -39,6 +39,8 @@ local schema = {
         realm = {type = "string"}, -- default is apisix
         logout_path = {type = "string"}, -- default is /logout
         redirect_uri = {type = "string"}, -- default is ngx.var.request_uri
+        public_key = {type = "string"},
+        token_signing_alg_values_expected = {type = "string"}
     },
     required = {"client_id", "client_secret", "discovery"}
 }
@@ -105,10 +107,20 @@ end
 
 local function introspect(ctx, conf)
     if has_bearer_access_token(ctx) or conf.bearer_only then
-        local res, err = openidc.introspect(conf)
-        if res then
-            return res
+        local res, err
+
+        if conf.public_key then
+            res, err = openidc.bearer_jwt_verify(conf)
+            if res then
+                return res
+            end
+        else
+            res, err = openidc.introspect(conf)
+            if res then
+                return res
+            end
         end
+
         if conf.bearer_only then
             ngx.header["WWW-Authenticate"] = 'Bearer realm="' .. conf.realm
                                              .. '",error="' .. err .. '"'
@@ -132,7 +144,7 @@ function _M.access(conf, ctx)
     end
 
     local response, err
-    if conf.introspection_endpoint then
+    if conf.introspection_endpoint or conf.public_key then
         response, err = introspect(ctx, conf)
         if err then
             core.log.error("failed to introspect in openidc: ", err)