simple-sso/src/ssso_nginx.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,
}