From e8374a1ecd68a76bd723a62a91d160579cebd8a9 Mon Sep 17 00:00:00 2001 From: Eguzki Astiz Lezaun Date: Fri, 19 Jan 2024 13:08:03 +0100 Subject: [PATCH] THREESCALE-10591 token instrospection field removed --- .../token_introspection.lua | 19 +- .../token_introspection_spec.lua | 304 ++++++++++-------- 2 files changed, 190 insertions(+), 133 deletions(-) diff --git a/gateway/src/apicast/policy/token_introspection/token_introspection.lua b/gateway/src/apicast/policy/token_introspection/token_introspection.lua index 3158e21cd..d76d7d844 100644 --- a/gateway/src/apicast/policy/token_introspection/token_introspection.lua +++ b/gateway/src/apicast/policy/token_introspection/token_introspection.lua @@ -94,7 +94,10 @@ function _M:access(context) local components = resty_url.parse(context.service.oidc.issuer_endpoint) self.credential = create_credential(components.user, components.password) - self.introspection_url = context.proxy.oauth.config.token_introspection_endpoint + local oauth_config = context.proxy.oauth.config + -- token_introspection_endpoint being deprecated in RH SSO 7.4 and removed in 7.5 + -- https://access.redhat.com/documentation/en-us/red_hat_single_sign-on/7.5/html-single/upgrading_guide/index#non_standard_token_introspection_endpoint_removed + self.introspection_url = oauth_config.introspection_endpoint or oauth_config.token_introspection_endpoint end if self.introspection_url then @@ -102,13 +105,17 @@ function _M:access(context) local access_token = authorization.token --- Introspection Response must have an "active" boolean value. -- https://tools.ietf.org/html/rfc7662#section-2.2 - if not introspect_token(self, access_token).active == true then - ngx.log(ngx.INFO, 'token introspection for access token ', access_token, ': token not active') - ngx.status = context.service.auth_failed_status - ngx.say(context.service.error_auth_failed) - return ngx.exit(ngx.status) + if introspect_token(self, access_token).active == true then + -- access granted + return end + + ngx.log(ngx.INFO, 'token introspection for access token ', access_token, ': token not active') end + + ngx.status = context.service.auth_failed_status + ngx.say(context.service.error_auth_failed) + return ngx.exit(ngx.status) end return _M diff --git a/spec/policy/token_introspection/token_introspection_spec.lua b/spec/policy/token_introspection/token_introspection_spec.lua index 1a63a249a..75ede9737 100644 --- a/spec/policy/token_introspection/token_introspection_spec.lua +++ b/spec/policy/token_introspection/token_introspection_spec.lua @@ -30,168 +30,218 @@ describe("token introspection policy", function() } end) - it('success with valid token', function() + describe('client_id+client_secret introspection auth type', function() + local auth_type = "client_id+client_secret" local introspection_url = "http://example/token/introspection" local policy_config = { - auth_type = "client_id+client_secret", + auth_type = auth_type, introspection_url = introspection_url, client_id = test_client_id, client_secret = test_client_secret } - test_backend - .expect{ - url = introspection_url, - method = 'POST', - headers = { - ['Authorization'] = test_basic_auth + + it('success with valid token', function() + test_backend + .expect{ + url = introspection_url, + method = 'POST', + headers = { + ['Authorization'] = test_basic_auth + } + } + .respond_with{ + status = 200, + body = cjson.encode({ + active = true + }) } - } - .respond_with{ - status = 200, - body = cjson.encode({ - active = true - }) - } - local token_policy = TokenIntrospection.new(policy_config) - token_policy.http_client.backend = test_backend - token_policy:access(context) - assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), - { token = "test", token_type_hint = "access_token" }) + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), + { token = "test", token_type_hint = "access_token" }) + end) - end) + it('failed with invalid token', function() + test_backend + .expect{ + url = introspection_url, + method = 'POST', + headers = { + ['Authorization'] = test_basic_auth + } + } + .respond_with{ + status = 200, + body = cjson.encode({ + active = false + }) + } + stub(ngx, 'say') + stub(ngx, 'exit') - it('failed with invalid token', function() - local introspection_url = "http://example/token/introspection" - local policy_config = { - auth_type = "client_id+client_secret", - introspection_url = introspection_url, - client_id = "client", - client_secret = "secret" - } + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert_authentication_failed() - test_backend - .expect{ - url = introspection_url, - method = 'POST', - headers = { - ['Authorization'] = test_basic_auth + assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), + { token = "test", token_type_hint = "access_token" }) + end) + + it('failed with bad status code', function() + test_backend + .expect{ + url = introspection_url, + method = 'POST', + headers = { + ['Authorization'] = test_basic_auth + } } - } - .respond_with{ - status = 200, - body = cjson.encode({ - active = false - }) - } - stub(ngx, 'say') - stub(ngx, 'exit') + .respond_with{ + status = 404, + } + stub(ngx, 'say') + stub(ngx, 'exit') - local token_policy = TokenIntrospection.new(policy_config) - token_policy.http_client.backend = test_backend - token_policy:access(context) - assert_authentication_failed() + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert_authentication_failed() - assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), - { token = "test", token_type_hint = "access_token" }) - end) + assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), + { token = "test", token_type_hint = "access_token" }) + end) - it('failed with bad status code', function() - local introspection_url = "http://example/token/introspection" - local policy_config = { - auth_type = "client_id+client_secret", - introspection_url = introspection_url, - client_id = "client", - client_secret = "secret" - } + it('failed with null response', function() + test_backend + .expect{ + url = introspection_url, + method = 'POST', + headers = { + ['Authorization'] = test_basic_auth + } + } + .respond_with{ + status = 200, + body = 'null' + } + stub(ngx, 'say') + stub(ngx, 'exit') + + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert_authentication_failed() + + assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), + { token = "test", token_type_hint = "access_token" }) + end) - test_backend - .expect{ - url = introspection_url, - method = 'POST', - headers = { - ['Authorization'] = test_basic_auth + it('failed with active null response', function() + test_backend + .expect{ + url = introspection_url, + method = 'POST', + headers = { + ['Authorization'] = test_basic_auth + } } - } - .respond_with{ - status = 404, - } - stub(ngx, 'say') - stub(ngx, 'exit') + .respond_with{ + status = 200, + body = '{ "active": null }' + } + stub(ngx, 'say') + stub(ngx, 'exit') - local token_policy = TokenIntrospection.new(policy_config) - token_policy.http_client.backend = test_backend - token_policy:access(context) - assert_authentication_failed() + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert_authentication_failed() - assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), - { token = "test", token_type_hint = "access_token" }) - end) + assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), + { token = "test", token_type_hint = "access_token" }) + end) - it('failed with null response', function() - local introspection_url = "http://example/token/introspection" - local policy_config = { - auth_type = "client_id+client_secret", - introspection_url = introspection_url, - client_id = "client", - client_secret = "secret" - } + it('failed with missing active response', function() + test_backend + .expect{ + url = introspection_url, + method = 'POST', + headers = { + ['Authorization'] = test_basic_auth + } + } + .respond_with{ + status = 200, + body = '{}' + } + stub(ngx, 'say') + stub(ngx, 'exit') + + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert_authentication_failed() + + assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), + { token = "test", token_type_hint = "access_token" }) + end) - test_backend - .expect{ - url = introspection_url, - method = 'POST', - headers = { - ['Authorization'] = test_basic_auth + it('failed with bad contents type', function() + test_backend + .expect{ + url = introspection_url, + method = 'POST', + headers = { + ['Authorization'] = test_basic_auth + } } - } - .respond_with{ - status = 200, - body = 'null' - } - stub(ngx, 'say') - stub(ngx, 'exit') + .respond_with{ + status = 200, + body = "" + } + stub(ngx, 'say') + stub(ngx, 'exit') - local token_policy = TokenIntrospection.new(policy_config) - token_policy.http_client.backend = test_backend - token_policy:access(context) - assert_authentication_failed() + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert_authentication_failed() - assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), - { token = "test", token_type_hint = "access_token" }) + assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), + { token = "test", token_type_hint = "access_token" }) + end) end) - it('failed with bad contents type', function() + describe('use_3scale_oidc_issuer_endpoint introspection auth type', function() + local auth_type = "use_3scale_oidc_issuer_endpoint" local introspection_url = "http://example/token/introspection" local policy_config = { - auth_type = "client_id+client_secret", + auth_type = auth_type, introspection_url = introspection_url, - client_id = "client", - client_secret = "secret" + client_id = test_client_id, + client_secret = test_client_secret } - test_backend - .expect{ - url = introspection_url, - method = 'POST', - headers = { - ['Authorization'] = test_basic_auth + it('no oauth content in the context', function() + context = { + service = { + auth_failed_status = 403, + error_auth_failed = "auth failed" } } - .respond_with{ - status = 200, - body = "" - } - stub(ngx, 'say') - stub(ngx, 'exit') - local token_policy = TokenIntrospection.new(policy_config) - token_policy.http_client.backend = test_backend - token_policy:access(context) - assert_authentication_failed() + stub(ngx, 'say') + stub(ngx, 'exit') + + local token_policy = TokenIntrospection.new(policy_config) + token_policy.http_client.backend = test_backend + token_policy:access(context) + assert_authentication_failed() + end) - assert.are.same(ngx.decode_args(test_backend.get_requests()[1].body), - { token = "test", token_type_hint = "access_token" }) end) describe('when caching is enabled', function()