diff --git a/doc/plugins/oauth.md b/doc/plugins/oauth.md index 3ecfeeac6461..3b3f0e62fd6e 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 17a0538b924d..6a93226f9baa 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)