Skip to content

Commit 20823bc

Browse files
committed
add auth_type to get properties from the oidc issuer setting
1 parent 19f37eb commit 20823bc

File tree

6 files changed

+222
-20
lines changed

6 files changed

+222
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2020
- `APICAST_ACCESS_LOG_FILE` env to make the access log location configurable [THREESCALE-743](https://github.com/3scale/apicast/pull/743)
2121
- ENV variables to make APIcast listen on HTTPS port [PR #622](https://github.com/3scale/apicast/pull/622)
2222
- New `ssl_certificate` phase allows policies to provide certificate to terminate HTTPS connection [PR #622](https://github.com/3scale/apicast/pull/622).
23+
- Configurable `auth_type` for the token introspection policy [PR #755](https://github.com/3scale/apicast/pull/755)
2324

2425
### Changed
2526

examples/policies/token_introspection_configuration.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
local policy_chain = require('apicast.policy_chain').default()
22

33
local token_policy = require('apicast.policy.token_introspection').new({
4+
auth_type = "client_id+client_secret",
45
introspection_url = "http://localhost:8080/auth/realms/3scale/protocol/openid-connect/token/introspect",
56
client_id = "YOUR_CLIENT_ID",
67
client_secret = "YOUR_CLIENT_SECRET"

gateway/src/apicast/policy/token_introspection/apicast-policy.json

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,17 @@
22
"$schema": "http://apicast.io/poolicy-v1/schema#manifest#",
33
"name": "OAuth 2.0 Token Introspection",
44
"summary": "Configures OAuth 2.0 Token Introspection.",
5-
"description":
6-
["This policy executes OAuth 2.0 Token Introspection ",
7-
"(https://tools.ietf.org/html/rfc7662) for every API call."],
5+
"description": ["This policy executes OAuth 2.0 Token Introspection ",
6+
"(https://tools.ietf.org/html/rfc7662) for every API call."
7+
],
88
"version": "builtin",
99
"configuration": {
1010
"type": "object",
1111
"properties": {
12-
"introspection_url": {
13-
"description": "Introspection Endpoint URL",
14-
"type": "string"
15-
},
16-
"client_id": {
17-
"description": "Client ID for the Token Introspection Endpoint",
18-
"type": "string"
19-
},
20-
"client_secret": {
21-
"description": "Client Secret for the Token Introspection Endpoint",
22-
"type": "string"
12+
"auth_type": {
13+
"type": "string",
14+
"enum": ["use_3scale_oidc_issuer_endpoint", "client_id+client_secret"],
15+
"default": "client_id+client_secret"
2316
},
2417
"max_ttl_tokens": {
2518
"description": "Max TTL for cached tokens",
@@ -33,6 +26,43 @@
3326
"minimum": 0,
3427
"maximum": 10000
3528
}
29+
},
30+
"required": [
31+
"auth_type"
32+
],
33+
"dependencies": {
34+
"auth_type": {
35+
"oneOf": [{
36+
"properties": {
37+
"auth_type": {
38+
"describe": "Use the Client credentials and the Token Introspection Endpoint from the OpenID Connect Issuer setting.",
39+
"enum": ["use_3scale_oidc_issuer_endpoint"]
40+
}
41+
}
42+
}, {
43+
"properties": {
44+
"auth_type": {
45+
"describe": "Specify the Token Introspection Endpoint, Client ID, and Client Secret.",
46+
"enum": ["client_id+client_secret"]
47+
},
48+
"client_id": {
49+
"description": "Client ID for the Token Introspection Endpoint",
50+
"type": "string"
51+
},
52+
"client_secret": {
53+
"description": "Client Secret for the Token Introspection Endpoint",
54+
"type": "string"
55+
},
56+
"introspection_url": {
57+
"description": "Introspection Endpoint URL",
58+
"type": "string"
59+
}
60+
},
61+
"required": [
62+
"client_id", "client_secret", "introspection_url"
63+
]
64+
}]
65+
}
3666
}
3767
}
3868
}

gateway/src/apicast/policy/token_introspection/token_introspection.lua

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local http_authorization = require 'resty.http_authorization'
66
local http_ng = require 'resty.http_ng'
77
local user_agent = require 'apicast.user_agent'
88
local resty_env = require('resty.env')
9+
local resty_url = require('resty.url')
910

1011
local tokens_cache = require('tokens_cache')
1112

@@ -16,19 +17,25 @@ local new = _M.new
1617
local noop = function() end
1718
local noop_cache = { get = noop, set = noop }
1819

20+
local function create_credential(client_id, client_secret)
21+
return 'Basic ' .. ngx.encode_base64(table.concat({ client_id, client_secret }, ':'))
22+
end
23+
1924
function _M.new(config)
2025
local self = new(config)
2126
self.config = config or {}
27+
self.auth_type = config.auth_type or "client_id+client_secret"
2228
--- authorization for the token introspection endpoint.
2329
-- https://tools.ietf.org/html/rfc7662#section-2.2
24-
local credential = 'Basic ' .. ngx.encode_base64(table.concat({ self.config.client_id or '', self.config.client_secret or '' }, ':'))
25-
self.introspection_url = config.introspection_url
30+
if self.auth_type == "client_id+client_secret" then
31+
self.credential = create_credential(self.config.client_id or '', self.config.client_secret or '')
32+
self.introspection_url = config.introspection_url
33+
end
2634
self.http_client = http_ng.new{
2735
backend = config.client,
2836
options = {
2937
headers = {
30-
['User-Agent'] = user_agent(),
31-
['Authorization'] = credential
38+
['User-Agent'] = user_agent()
3239
},
3340
ssl = { verify = resty_env.enabled('OPENSSL_VERIFY') }
3441
}
@@ -55,7 +62,8 @@ local function introspect_token(self, token)
5562

5663
--- Parameters for the token introspection endpoint.
5764
-- https://tools.ietf.org/html/rfc7662#section-2.1
58-
local res, err = self.http_client.post(self.introspection_url , { token = token, token_type_hint = 'access_token'})
65+
local res, err = self.http_client.post{self.introspection_url , { token = token, token_type_hint = 'access_token'},
66+
headers = {['Authorization'] = self.credential}}
5967
if err then
6068
ngx.log(ngx.WARN, 'token introspection error: ', err, ' url: ', self.introspection_url)
6169
return { active = false }
@@ -77,6 +85,18 @@ local function introspect_token(self, token)
7785
end
7886

7987
function _M:access(context)
88+
if self.auth_type == "use_3scale_oidc_issuer_endpoint" then
89+
if not context.proxy.oauth then
90+
ngx.status = context.service.auth_failed_status
91+
ngx.say(context.service.error_auth_failed)
92+
return ngx.exit(ngx.status)
93+
end
94+
95+
local components = resty_url.parse(context.service.oidc.issuer_endpoint)
96+
self.credential = create_credential(components.user, components.password)
97+
self.introspection_url = context.proxy.oauth.config.openid.token_introspection_endpoint
98+
end
99+
80100
if self.introspection_url then
81101
local authorization = http_authorization.new(ngx.var.http_authorization)
82102
local access_token = authorization.token

spec/policy/token_introspection/token_introspection_spec.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ describe("token introspection policy", function()
3333
it('success with valid token', function()
3434
local introspection_url = "http://example/token/introspection"
3535
local policy_config = {
36+
auth_type = "client_id+client_secret",
3637
introspection_url = introspection_url,
3738
client_id = test_client_id,
3839
client_secret = test_client_secret
@@ -61,6 +62,7 @@ describe("token introspection policy", function()
6162
it('failed with invalid token', function()
6263
local introspection_url = "http://example/token/introspection"
6364
local policy_config = {
65+
auth_type = "client_id+client_secret",
6466
introspection_url = introspection_url,
6567
client_id = "client",
6668
client_secret = "secret"
@@ -93,6 +95,7 @@ describe("token introspection policy", function()
9395
it('failed with bad status code', function()
9496
local introspection_url = "http://example/token/introspection"
9597
local policy_config = {
98+
auth_type = "client_id+client_secret",
9699
introspection_url = introspection_url,
97100
client_id = "client",
98101
client_secret = "secret"
@@ -122,6 +125,7 @@ describe("token introspection policy", function()
122125
it('failed with null response', function()
123126
local introspection_url = "http://example/token/introspection"
124127
local policy_config = {
128+
auth_type = "client_id+client_secret",
125129
introspection_url = introspection_url,
126130
client_id = "client",
127131
client_secret = "secret"
@@ -152,6 +156,7 @@ describe("token introspection policy", function()
152156
it('failed with bad contents type', function()
153157
local introspection_url = "http://example/token/introspection"
154158
local policy_config = {
159+
auth_type = "client_id+client_secret",
155160
introspection_url = introspection_url,
156161
client_id = "client",
157162
client_secret = "secret"
@@ -182,6 +187,7 @@ describe("token introspection policy", function()
182187
describe('when caching is enabled', function()
183188
local introspection_url = "http://example/token/introspection"
184189
local policy_config = {
190+
auth_type = "client_id+client_secret",
185191
introspection_url = introspection_url,
186192
client_id = test_client_id,
187193
client_secret = test_client_secret,
@@ -241,4 +247,3 @@ describe("token introspection policy", function()
241247
end)
242248
end)
243249
end)
244-

0 commit comments

Comments
 (0)