188 lines
4.7 KiB
Lua
188 lines
4.7 KiB
Lua
local ngx = require("ngx")
|
|
local b64 = require("ssso_base64")
|
|
local util = require("ssso_util")
|
|
local conf = require("ssso_config")
|
|
|
|
local function get_request()
|
|
local vars = ngx.var
|
|
local request = {
|
|
referer = vars.http_referer,
|
|
host = vars.host,
|
|
method = vars.request_method,
|
|
uri = vars.request_uri,
|
|
}
|
|
if request.referer == "" then
|
|
request.referer = nil
|
|
end
|
|
|
|
local target, qp = request.uri, {}
|
|
local qm, _ = target:find("%?")
|
|
if qm then
|
|
qp = ngx.decode_args(target:sub(qm + 1))
|
|
target = target:sub(1, qm - 1)
|
|
end
|
|
request["target"] = target
|
|
request["query_params"] = qp
|
|
|
|
local https = vars.proxy_https or vars.https
|
|
if https and https ~= "" then
|
|
request["scheme"] = "https"
|
|
else
|
|
request["scheme"] = "http"
|
|
end
|
|
return request
|
|
end
|
|
|
|
local function with_post_parameters(req_data)
|
|
ngx.req.read_body()
|
|
local args, _ = ngx.req.get_post_args()
|
|
if args then
|
|
for key, val in pairs(args) do
|
|
req_data.query_params[key] = val
|
|
end
|
|
end
|
|
return req_data
|
|
end
|
|
|
|
local function str_starts_with(str, begin)
|
|
local i, _ = str:find(util.str_to_pattern(begin))
|
|
return 1 == i
|
|
end
|
|
|
|
local function get_basic_auth()
|
|
local header = ngx.var.Authentication
|
|
if (not header) or (#header < 7) or (not str_starts_with(header, "Basic ")) then
|
|
return nil, nil
|
|
end
|
|
local text, _ = b64.decode_base64(header:sub(7))
|
|
if not text then
|
|
ngx.log(ngx.DEBUG, "Invalid Authentication header: " .. header)
|
|
return nil, nil
|
|
end
|
|
local colon
|
|
colon, _ = text:find(":")
|
|
if not colon then
|
|
return nil, nil
|
|
end
|
|
local login, password = "", ""
|
|
if colon > 1 then
|
|
login = text:sub(1, colon - 1)
|
|
end
|
|
if colon < #text then
|
|
password = text:sub(colon + 1, #text)
|
|
end
|
|
return login, password
|
|
end
|
|
|
|
local function get_jws_cookie()
|
|
return ngx.var.cookie_SSSO_TOKEN
|
|
end
|
|
|
|
local function set_jws_cookie(jws, tslimit)
|
|
ngx.header["Set-Cookie"] = "SSSO_TOKEN=" .. jws ..
|
|
"; Path=/; Expires=" .. ngx.cookie_time(tslimit) ..
|
|
"; Secure"
|
|
end
|
|
|
|
local function get_seconds_since_epoch()
|
|
return math.floor(ngx.now())
|
|
end
|
|
|
|
local function add_cookie(name, value)
|
|
local cookie = name .. "=" .. value
|
|
local old_cookie = ngx.var.http_cookie
|
|
if old_cookie and old_cookie ~= "" then
|
|
cookie = old_cookie .. "; " .. cookie
|
|
end
|
|
ngx.log(ngx.DEBUG, "Overriding request Cookie header: " .. cookie)
|
|
ngx.req.set_header("Cookie", cookie)
|
|
end
|
|
|
|
local function add_header(name, value)
|
|
ngx.log(ngx.DEBUG, "Setting request " .. name .. " header: " .. value)
|
|
ngx.req.set_header(name, value)
|
|
end
|
|
|
|
local function has_method(req_data, method)
|
|
return string.upper(method) == string.upper(req_data.method)
|
|
end
|
|
|
|
local function is(req_data, url)
|
|
return req_data.target == url
|
|
end
|
|
|
|
local function matches(req_data, lua_pattern)
|
|
return req_data.target:match(lua_pattern)
|
|
end
|
|
|
|
local function starts_with(req_data, prefix)
|
|
return str_starts_with(req_data.target, prefix)
|
|
end
|
|
|
|
local function has_param(req_data, param, value)
|
|
return req_data.query_params[param] ~= nil and (value == nil or req_data.query_params[param] == value)
|
|
end
|
|
|
|
local function answer_not_found(req_data)
|
|
return ngx.exit(404)
|
|
end
|
|
|
|
local function answer_unexpected_error()
|
|
ngx.log(ngx.ERROR, "Unexpected Simple-SSO error.")
|
|
return ngx.exit(500)
|
|
end
|
|
|
|
local function redirect_to_page(uri)
|
|
return ngx.redirect("https://" .. conf.get_sso_host() .. uri, 302)
|
|
end
|
|
|
|
local function redirect_to_login(req_data, status)
|
|
return ngx.redirect("https://" ..
|
|
conf.get_sso_host() ..
|
|
conf.get_sso_prefix() ..
|
|
"/login?back=" ..
|
|
ngx.escape_uri(req_data.uri) ..
|
|
"&cause=" .. tostring(status),
|
|
307)
|
|
end
|
|
|
|
local function redirect_to_portal()
|
|
return ngx.redirect("https://" .. conf.get_sso_host() .. conf.get_sso_prefix() .. "/portal", 307)
|
|
end
|
|
|
|
local function return_contents(contents, mime_and_charset)
|
|
ngx.header["Content-Type"] = mime_and_charset
|
|
ngx.header["Content-Length"] = tostring(#contents)
|
|
ngx.header["Cache-Control"] = "no-store,max-age=0"
|
|
ngx.say(contents)
|
|
-- TODO: CSRF
|
|
return ngx.exit(200)
|
|
end
|
|
|
|
local function forward_request(req_data)
|
|
return
|
|
end
|
|
|
|
return {
|
|
add_cookie = add_cookie,
|
|
add_header = add_header,
|
|
answer_not_found = answer_not_found,
|
|
forward_request = forward_request,
|
|
get_basic_auth = get_basic_auth,
|
|
get_jws_cookie = get_jws_cookie,
|
|
get_request = get_request,
|
|
get_seconds_since_epoch = get_seconds_since_epoch,
|
|
has_method = has_method,
|
|
has_param = has_param,
|
|
is = is,
|
|
matches = matches,
|
|
redirect_to_login = redirect_to_login,
|
|
redirect_to_page = redirect_to_page,
|
|
redirect_to_portal = redirect_to_portal,
|
|
return_contents = return_contents,
|
|
set_jws_cookie = set_jws_cookie,
|
|
starts_with = starts_with,
|
|
answer_unexpected_error = answer_unexpected_error,
|
|
with_post_parameters = with_post_parameters,
|
|
}
|