Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support to public key based introspection for OAuth plugin #1266

Merged
merged 3 commits into from
Mar 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions doc/plugins/oauth.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
20 changes: 16 additions & 4 deletions lua/apisix/plugins/openid-connect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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"}
}
Expand Down Expand Up @@ -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 .. '"'
Expand All @@ -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)
Expand Down