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

Fix OAuth auth caching #304

Merged
merged 5 commits into from
Mar 16, 2017
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed

- Reloading of configuration with every request when cache is disabled [PR #287](https://github.com/3scale/apicast/pull/287)
- Auth caching is not used when OAuth method is used [PR #304](https://github.com/3scale/apicast/pull/304)

## [3.0.0-beta1] - 2017-03-03

Expand Down
41 changes: 5 additions & 36 deletions apicast/src/proxy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -150,31 +150,9 @@ local http = {
end
}

local function oauth_authrep(service)
local cached_key = ngx.var.cached_key .. ":" .. ngx.var.usage
local access_tokens = assert(ngx.shared.api_keys, 'missing shared dictionary: api_keys')
local is_known = access_tokens:get(cached_key)

if is_known == 200 then
ngx.log(ngx.DEBUG, 'apicast cache hit key: ', cached_key)
ngx.var.cached_key = cached_key
else
local res = http.get("/threescale_oauth_authrep")

if res.status ~= 200 then
access_tokens:delete(ngx.var.cached_key)
ngx.status = res.status
ngx.header.content_type = "application/json"
error_authorization_failed(service)
else
access_tokens:set(ngx.var.cached_key,200)
end

ngx.var.cached_key = nil
end
end

local function authrep(service)
function _M.authorize(service)
local internal_location = (service.backend_version == 'oauth' and '/threescale_oauth_authrep')
or '/threescale_authrep'
-- NYI: return to lower frame
local cached_key = ngx.var.cached_key .. ":" .. ngx.var.usage
local api_keys = ngx.shared.api_keys
Expand All @@ -185,7 +163,7 @@ local function authrep(service)
ngx.var.cached_key = cached_key
else
ngx.log(ngx.INFO, 'apicast cache miss key: ', cached_key)
local res = http.get("/threescale_authrep")
local res = http.get(internal_location)

ngx.log(ngx.DEBUG, '[backend] response status: ', res.status, ' body: ', res.body)

Expand All @@ -206,14 +184,6 @@ local function authrep(service)
end
end

function _M.authorize(backend_version, service)
if backend_version == 'oauth' then
oauth_authrep(service)
else
authrep(service)
end
end

function _M:set_service(host)
host = host or ngx.var.host
local service = self:find_service(host)
Expand Down Expand Up @@ -294,7 +264,6 @@ function _M:call(host)
end

function _M:access(service)
local backend_version = service.backend_version

if ngx.status == 403 then
ngx.say("Throttling due to too many requests")
Expand Down Expand Up @@ -349,7 +318,7 @@ function _M:access(service)
ngx.header["X-3scale-hostname"] = ngx.var.hostname
end

self.authorize(backend_version, service)
self.authorize(service)
end


Expand Down
59 changes: 59 additions & 0 deletions t/009-apicast-caching.t
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,62 @@ apicast cache miss key: 1:one-key:usage%5Bhits%5D=1
apicast cache write key: 1:one-key:usage%5Bhits%5D=1
apicast cache miss key: 2:two-id:two-key:usage%5Bhits%5D=2
apicast cache write key: 2:two-id:two-key:usage%5Bhits%5D=2

=== TEST 7: call to backend is cached
First call is done synchronously and the second out of band.
--- http_config
include $TEST_NGINX_UPSTREAM_CONFIG;
lua_package_path "$TEST_NGINX_LUA_PATH";
init_by_lua_block {
require('configuration_loader').mock({
services = {
{
id = 42,
backend_version = 'oauth',
proxy = {
credentials_location = "query",
api_backend = "http://127.0.0.1:$TEST_NGINX_SERVER_PORT/api-backend/",
proxy_rules = {
{ pattern = '/', http_method = 'GET', metric_system_name = 'hits', delta = 2 }
}
}
}
}
})
}
lua_shared_dict api_keys 10m;
--- config
include $TEST_NGINX_APICAST_CONFIG;

set $backend_endpoint 'http://127.0.0.1:$TEST_NGINX_SERVER_PORT';
set $backend_authentication_type 'service_token';
set $backend_authentication_value 'token-value';

location /transactions/oauth_authrep.xml {
content_by_lua_block { ngx.exit(200) }
}

location /api-backend/ {
echo 'yay, api backend';
}

location ~ /test/(.+) {
proxy_pass $scheme://127.0.0.1:$server_port/$1$is_args$args;
proxy_set_header Host localhost;
}

location = /t {
echo_subrequest GET /test/one -q access_token=value;
echo_subrequest GET /test/two -q access_token=value;
}
--- request
GET /t
--- response_body
yay, api backend
yay, api backend
--- error_code: 200
--- grep_error_log eval: qr/apicast cache (?:hit|miss|write) key: [^,\s]+/
--- grep_error_log_out
apicast cache miss key: 42:value:usage%5Bhits%5D=2
apicast cache write key: 42:value:usage%5Bhits%5D=2
apicast cache hit key: 42:value:usage%5Bhits%5D=2