spacewander commented on a change in pull request #2903:
URL: https://github.com/apache/apisix/pull/2903#discussion_r533834596
##########
File path: apisix/plugins/openid-connect.lua
##########
@@ -93,59 +118,124 @@ function _M.check_schema(conf)
end
-local function has_bearer_access_token(ctx)
+local function check_bearer_access_token(ctx)
+ -- Get Authorization header, maybe.
local auth_header = core.request.header(ctx, "Authorization")
if not auth_header then
- return false
+ -- No Authorization header, get X-Access-Token header, maybe.
+ local access_token_header = core.request.header(ctx, "X-Access-Token")
+ if not access_token_header then
+ -- No X-Access-Token header neither.
+ return false, nil, nil
+ end
+
+ -- Return extracted header value.
+ return true, access_token_header, nil
end
+ -- Check format of Authorization header.
local res, err = ngx_re.split(auth_header, " ", nil, nil, 2)
if not res then
- return false, err
+ return false, nil, err
end
- if res[1] == "bearer" then
- return true
+ if string.lower(res[1]) == "bearer" then
+ -- Return extracted token.
+ return true, res[2], nil
end
return false
end
+local function set_header(ctx, name, value)
+ -- Set a request header to the given value and update the cached headers
in the context as well.
+
+ -- Set header in request.
+ ngx.req.set_header(name, value)
+
+ -- Set header in cache, maybe.
+ if ctx and ctx.headers then
+ ctx.headers[name] = value
+ end
+end
+
+
+local function add_user_header(ctx, user)
+ local userinfo = core.json.encode(user)
+ set_header(ctx, "X-Userinfo", ngx_encode_base64(userinfo))
+end
+
+
+local function add_access_token_header(ctx, conf, token)
+ -- Add Authorization or X-Access-Token header, respectively, if not
already set.
+ if conf.set_access_token_header then
+ if conf.access_token_in_authorization_header then
+ if not core.request.header(ctx, "Authorization") then
+ -- Add Authorization header.
+ set_header(ctx, "Authorization", "Bearer " .. token)
+ end
+ else
+ if not core.request.header(ctx, "X-Access-Token") then
+ -- Add X-Access-Token header.
+ set_header(ctx, "X-Access-Token", token)
+ end
+ end
+ end
+end
+
+
local function introspect(ctx, conf)
- if has_bearer_access_token(ctx) or conf.bearer_only then
+ -- Extract token, maybe. Ignore errors.
+ local has_token, token, _ = check_bearer_access_token(ctx)
+
+ -- Check if token was extracted or if we always require a token in the
request.
+ if has_token or conf.bearer_only then
local res, err
if conf.public_key then
+ -- Validate token against public key.
res, err = openidc.bearer_jwt_verify(conf)
if res then
+ -- Token is valid.
+
+ -- Add configured access token header, maybe.
+ add_access_token_header(ctx, conf, token)
Review comment:
Token is invalid if has_token is false but conf.bearer_only is true
##########
File path: apisix/plugins/openid-connect.lua
##########
@@ -93,59 +118,124 @@ function _M.check_schema(conf)
end
-local function has_bearer_access_token(ctx)
+local function check_bearer_access_token(ctx)
+ -- Get Authorization header, maybe.
local auth_header = core.request.header(ctx, "Authorization")
if not auth_header then
- return false
+ -- No Authorization header, get X-Access-Token header, maybe.
+ local access_token_header = core.request.header(ctx, "X-Access-Token")
+ if not access_token_header then
+ -- No X-Access-Token header neither.
+ return false, nil, nil
+ end
+
+ -- Return extracted header value.
+ return true, access_token_header, nil
end
+ -- Check format of Authorization header.
local res, err = ngx_re.split(auth_header, " ", nil, nil, 2)
if not res then
- return false, err
+ return false, nil, err
end
- if res[1] == "bearer" then
- return true
+ if string.lower(res[1]) == "bearer" then
+ -- Return extracted token.
+ return true, res[2], nil
end
return false
end
+local function set_header(ctx, name, value)
+ -- Set a request header to the given value and update the cached headers
in the context as well.
+
+ -- Set header in request.
+ ngx.req.set_header(name, value)
+
+ -- Set header in cache, maybe.
+ if ctx and ctx.headers then
+ ctx.headers[name] = value
+ end
+end
+
+
+local function add_user_header(ctx, user)
+ local userinfo = core.json.encode(user)
+ set_header(ctx, "X-Userinfo", ngx_encode_base64(userinfo))
+end
+
+
+local function add_access_token_header(ctx, conf, token)
+ -- Add Authorization or X-Access-Token header, respectively, if not
already set.
+ if conf.set_access_token_header then
+ if conf.access_token_in_authorization_header then
+ if not core.request.header(ctx, "Authorization") then
+ -- Add Authorization header.
+ set_header(ctx, "Authorization", "Bearer " .. token)
+ end
+ else
+ if not core.request.header(ctx, "X-Access-Token") then
+ -- Add X-Access-Token header.
+ set_header(ctx, "X-Access-Token", token)
+ end
+ end
+ end
+end
+
+
local function introspect(ctx, conf)
- if has_bearer_access_token(ctx) or conf.bearer_only then
+ -- Extract token, maybe. Ignore errors.
+ local has_token, token, _ = check_bearer_access_token(ctx)
+
+ -- Check if token was extracted or if we always require a token in the
request.
+ if has_token or conf.bearer_only then
local res, err
if conf.public_key then
+ -- Validate token against public key.
res, err = openidc.bearer_jwt_verify(conf)
if res then
+ -- Token is valid.
+
+ -- Add configured access token header, maybe.
+ add_access_token_header(ctx, conf, token)
return res
end
else
+ -- Validate token against introspection endpoint.
res, err = openidc.introspect(conf)
if err then
return ngx.HTTP_UNAUTHORIZED, err
else
+ -- Token is valid and res contains the response from the
introspection endpoint.
+
+ if conf.set_userinfo_token_header then
+ -- Set X-Userinfo header to introspection endpoint
response.
+ add_user_header(ctx, res)
+ end
+
+ -- Add configured access token header, maybe.
+ add_access_token_header(ctx, conf, token)
Review comment:
Ditto
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]