Limited support for app-logout on SSO-logout
parent
049ad9f48a
commit
de20c91871
|
@ -164,6 +164,10 @@ Array of regular expressions to be matched against URLS **and** URIs and their r
|
||||||
|
|
||||||
2-level array containing usernames and their allowed URLs along with an App name (**example**: `{ "kload": { "kload.fr/myapp/": "My App" } }`)
|
2-level array containing usernames and their allowed URLs along with an App name (**example**: `{ "kload": { "kload.fr/myapp/": "My App" } }`)
|
||||||
|
|
||||||
|
#### logout
|
||||||
|
|
||||||
|
Associative array; when logging out of SSOwat, any existing cookie that is found as a key of this array triggers the associated logout URL. This only works on `http[s]://[*.]portal_domaini/`, though. (**example**: `{ "dcxd": "https://example.org/dotclear/admin/index.php?logout=1" }`)
|
||||||
|
|
||||||
#### default_language
|
#### default_language
|
||||||
|
|
||||||
Language code used by default in views (**default**: `en`)
|
Language code used by default in views (**default**: `en`)
|
||||||
|
|
|
@ -42,6 +42,15 @@ end
|
||||||
ngx.header["X-SSO-WAT"] = "You've just been SSOed"
|
ngx.header["X-SSO-WAT"] = "You've just been SSOed"
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- 0. LOGOUT if requested, but only if logged in
|
||||||
|
--
|
||||||
|
local logout_ck = ngx.var.cookie_SSOwFullLogout
|
||||||
|
if logout_ck and logout_ck ~= "" and hlp.is_logged_in() then
|
||||||
|
return hlp.logout()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- 1. LOGIN
|
-- 1. LOGIN
|
||||||
--
|
--
|
||||||
|
|
|
@ -26,5 +26,8 @@
|
||||||
"example.org/myapp": "My other domain App",
|
"example.org/myapp": "My other domain App",
|
||||||
"example.com/myapp2": "My second App"
|
"example.com/myapp2": "My second App"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"logout": {
|
||||||
|
"dcxd": "https://example.org/dotclear/admin/index.php?logout=1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ function get_config()
|
||||||
portal_scheme = "https",
|
portal_scheme = "https",
|
||||||
portal_path = "/ssowat/",
|
portal_path = "/ssowat/",
|
||||||
local_portal_domain = "yunohost.local",
|
local_portal_domain = "yunohost.local",
|
||||||
domains = { conf["portal_domain"], "yunohost.local" },
|
domains = { "yunohost.local", conf["portal_domain"] },
|
||||||
session_timeout = 60 * 60 * 24, -- one day
|
session_timeout = 60 * 60 * 24, -- one day
|
||||||
session_max_timeout = 60 * 60 * 24 * 7, -- one week
|
session_max_timeout = 60 * 60 * 24 * 7, -- one week
|
||||||
login_arg = "sso_login",
|
login_arg = "sso_login",
|
||||||
|
@ -53,6 +53,7 @@ function get_config()
|
||||||
ldap_enforce_crypt = true,
|
ldap_enforce_crypt = true,
|
||||||
skipped_urls = {},
|
skipped_urls = {},
|
||||||
users = {},
|
users = {},
|
||||||
|
logout = {},
|
||||||
ldap_attributes = {"uid", "givenname", "sn", "cn", "homedirectory", "mail", "maildrop"},
|
ldap_attributes = {"uid", "givenname", "sn", "cn", "homedirectory", "mail", "maildrop"},
|
||||||
additional_headers = {["Remote-User"] = "uid"},
|
additional_headers = {["Remote-User"] = "uid"},
|
||||||
allow_mail_authentication = true,
|
allow_mail_authentication = true,
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
-- Redirect to the SSO if logout is in progress
|
||||||
|
if ngx.ctx.SSOwFullLogout then
|
||||||
|
local next_cookie, back_url = ngx.ctx.SSOwFullLogout:match('^(.-)|(http.+)$')
|
||||||
|
ngx.log(ngx.DEBUG, "LOGOUT STEP DONE; next: "..next_cookie..", back to: "..back_url)
|
||||||
|
ngx.status = ngx.HTTP_TEMPORARY_REDIRECT
|
||||||
|
ngx.header['Set-Cookie'] = {next_cookie}
|
||||||
|
ngx.header.Location = back_url
|
||||||
|
end
|
77
helpers.lua
77
helpers.lua
|
@ -55,6 +55,10 @@ function string.ends(String, End)
|
||||||
return End=='' or string.sub(String, -string.len(End)) == End
|
return End=='' or string.sub(String, -string.len(End)) == End
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Escape special characters in a string
|
||||||
|
function string.pcre_escape(String)
|
||||||
|
return ngx.re.gsub(String, '([]({+?\\*.})[])', '\\$1')
|
||||||
|
end
|
||||||
|
|
||||||
-- Find a string by its translate key in the right language
|
-- Find a string by its translate key in the right language
|
||||||
function t(key)
|
function t(key)
|
||||||
|
@ -177,7 +181,8 @@ function delete_cookie()
|
||||||
ngx.header["Set-Cookie"] = {
|
ngx.header["Set-Cookie"] = {
|
||||||
"SSOwAuthUser="..cookie_str,
|
"SSOwAuthUser="..cookie_str,
|
||||||
"SSOwAuthHash="..cookie_str,
|
"SSOwAuthHash="..cookie_str,
|
||||||
"SSOwAuthExpire="..cookie_str
|
"SSOwAuthExpire="..cookie_str,
|
||||||
|
"SSOwFullLogout="..cookie_str
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -883,18 +888,76 @@ end
|
||||||
-- It deletes session cached information to invalidate client side cookie
|
-- It deletes session cached information to invalidate client side cookie
|
||||||
-- information.
|
-- information.
|
||||||
function logout()
|
function logout()
|
||||||
|
conf = config.get_config()
|
||||||
|
|
||||||
-- We need this call since we are in a POST request
|
-- We need this call since we are in a POST request
|
||||||
local args = ngx.req.get_uri_args()
|
local args = ngx.req.get_uri_args()
|
||||||
|
|
||||||
-- Delete user cookie if logged in (that should always be the case)
|
-- Login if not logged in (that should always be the case)
|
||||||
if is_logged_in() then
|
if not is_logged_in() then
|
||||||
delete_cookie()
|
return redirect(conf.portal_url)
|
||||||
cache:delete("session_"..authUser)
|
|
||||||
cache:delete(authUser.."-"..conf["ldap_identifier"]) -- Ugly trick to reload cache
|
|
||||||
flash("info", t("logged_out"))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Loop over session cookies.
|
||||||
|
-- For now, this will only work for domains under that of SSOwat.
|
||||||
|
-- The SSOwFullLogout cookie always contains the next cookie to check.
|
||||||
|
local cur_logout_step = ngx.var.cookie_SSOwFullLogout or '*'
|
||||||
|
local url_re = "^(?:https?://(?:[^/]+\\.)?"..string.pcre_escape(conf['portal_domain'])..")?/"
|
||||||
|
local sess_ck
|
||||||
|
local sess_ck_val
|
||||||
|
local logout_url
|
||||||
|
local read_next_and_proceed = false
|
||||||
|
local cookie_str = "; Domain=."..conf['portal_domain']..
|
||||||
|
"; Path=/"..
|
||||||
|
"; Expires="..os.date("%a, %d %b %Y %X UTC;", ngx.req.start_time() + 60)
|
||||||
|
for sess_ck, logout_url in pairs(conf['logout']) do
|
||||||
|
ngx.log(ngx.DEBUG, "LOGOUT step="..cur_logout_step..", evaluate="..sess_ck)
|
||||||
|
|
||||||
|
-- Run a logout URL, but point to the next, to avoid a loop
|
||||||
|
if read_next_and_proceed then
|
||||||
|
ngx.ctx.SSOwFullLogout = "SSOwFullLogout="..sess_ck..cookie_str..'|'..conf.portal_url
|
||||||
|
ngx.log(ngx.DEBUG, "LOGOUT pass: "..req_data['request_uri'])
|
||||||
|
return pass()
|
||||||
|
|
||||||
|
-- A cookie must be checked; do so
|
||||||
|
elseif cur_logout_step == '*' or cur_logout_step == sess_ck then
|
||||||
|
if ngx.re.match(logout_url, url_re) then
|
||||||
|
|
||||||
|
-- Not the right URI for this cookie; redirect
|
||||||
|
if string.gsub(logout_url, '^https?://[^/]+/', '/') ~= req_data['request_uri'] then
|
||||||
|
ngx.header["Set-Cookie"] = {"SSOwFullLogout="..sess_ck..cookie_str}
|
||||||
|
ngx.log(ngx.DEBUG, "LOGOUT visit: "..logout_url)
|
||||||
|
return redirect(logout_url)
|
||||||
|
end
|
||||||
|
sess_ck_val = ngx.var["cookie_"..sess_ck]
|
||||||
|
|
||||||
|
-- The cookie must be deleted
|
||||||
|
if sess_ck_val and sess_ck_val ~= "" then
|
||||||
|
read_next_and_proceed = true
|
||||||
|
|
||||||
|
-- No cookie; check next
|
||||||
|
else
|
||||||
|
ngx.log(ngx.DEBUG, "LOGOUT skip")
|
||||||
|
cur_logout_step = '*'
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- This URL is not handled :-(
|
||||||
|
ngx.log(ngx.DEBUG, "LOGOUT unhandled")
|
||||||
|
cur_logout_step = '*'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if read_next_and_proceed then
|
||||||
|
ngx.ctx.SSOwFullLogout = "SSOwFullLogout=0"..cookie_str..'|'..conf.portal_url
|
||||||
|
ngx.log(ngx.DEBUG, "LOGOUT pass: "..req_data['request_uri'])
|
||||||
|
return pass()
|
||||||
|
end
|
||||||
|
|
||||||
|
delete_cookie()
|
||||||
|
cache:delete("session_"..authUser)
|
||||||
|
cache:delete(authUser.."-"..conf["ldap_identifier"]) -- Ugly trick to reload cache
|
||||||
|
flash("info", t("logged_out"))
|
||||||
|
|
||||||
-- Redirect to portal anyway
|
-- Redirect to portal anyway
|
||||||
return redirect(conf.portal_url)
|
return redirect(conf.portal_url)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue