implement proper expiration/prolong mechanism for cookies

This commit is contained in:
Alexandre Aubin 2023-11-28 18:04:29 +01:00
parent b0b128f53d
commit 6223239e94
2 changed files with 18 additions and 14 deletions

View file

@ -55,6 +55,7 @@ Only the `portal_domain` SSOwat configuration parameters is required, but it is
- `cookie_secret_file`: Where the secret used for signing and encrypting cookie is stored. It should only be readable by root. - `cookie_secret_file`: Where the secret used for signing and encrypting cookie is stored. It should only be readable by root.
- `cookie_name`: The name of the cookie used for authentication. Its content is expected to be a JWT signed with the cookie secret and should contain a key `user` and `password` (which is needed for Basic HTTP Auth). Because JWT is only encoded and signed (not encrypted), the `password` is expected to be encrypted using the cookie secret. - `cookie_name`: The name of the cookie used for authentication. Its content is expected to be a JWT signed with the cookie secret and should contain a key `user` and `password` (which is needed for Basic HTTP Auth). Because JWT is only encoded and signed (not encrypted), the `password` is expected to be encrypted using the cookie secret.
- `session_folder`: A path to a folder where files exists for any valid valid session id. SSOwat will check for the last modification date to confirm that the session is not expired.
- `domain_portal_urls`: Location of the portal to use for login and browsing apps, to redirect to when access to some route is denied - `domain_portal_urls`: Location of the portal to use for login and browsing apps, to redirect to when access to some route is denied
- `redirected_urls`: Array of URLs and/or URIs to redirect and their redirect URI/URL (**example**: `{ "/": "example.org/subpath" }`). - `redirected_urls`: Array of URLs and/or URIs to redirect and their redirect URI/URL (**example**: `{ "/": "example.org/subpath" }`).

View file

@ -11,6 +11,7 @@ ngx.header["X-SSO-WAT"] = "You've just been SSOed"
local jwt = require("vendor.luajwtjitsi.luajwtjitsi") local jwt = require("vendor.luajwtjitsi.luajwtjitsi")
local cipher = require('openssl.cipher') local cipher = require('openssl.cipher')
local rex = require("rex_pcre2") local rex = require("rex_pcre2")
local lfs = require("lfs")
-- ########################################################################### -- ###########################################################################
-- 0. Misc helpers because Lua has no sugar ... -- 0. Misc helpers because Lua has no sugar ...
@ -33,18 +34,18 @@ function cached_jwt_verify(data, secret)
decoded, err = jwt.verify(data, "HS256", cookie_secret) decoded, err = jwt.verify(data, "HS256", cookie_secret)
if not decoded then if not decoded then
logger:error(err) logger:error(err)
return nil, nil, err return nil, nil, nil, err
end end
-- As explained in set_basic_auth_header(), user and hashed password do not contain ':' -- As explained in set_basic_auth_header(), user and hashed password do not contain ':'
-- And cache cannot contain tables, so we use "user:password" format -- And cache cannot contain tables, so we use "id:user:password" format
cached = decoded["user"]..":"..decoded["pwd"] cached = decoded['id']..":"..decoded["user"]..":"..decoded["pwd"]
cache:set(data, cached, 120) cache:set(data, cached, 120)
logger:debug("Result saved in cache") logger:debug("Result saved in cache")
return decoded["user"], decoded["pwd"], err return decoded['id'], decoded["user"], decoded["pwd"], err
else else
logger:debug("Result found in cache") logger:debug("Result found in cache")
user, pwd = res:match("([^:]+):(.*)") session_id, user, pwd = res:match("([^:]+):([^:]+):(.*)")
return user, pwd, nil return session_id, user, pwd, nil
end end
end end
@ -109,18 +110,20 @@ function check_authentication()
return false, nil, nil return false, nil, nil
end end
user, pwd, err = cached_jwt_verify(cookie, cookie_secret) session_id, user, pwd, err = cached_jwt_verify(cookie, cookie_secret)
-- FIXME : maybe also check that the cookie was delivered for the requested domain (or a parent?)
-- FIXME : we might want also a way to identify expired/invalidated cookies,
-- e.g. a user that got deleted after being logged in, or a user that logged out ...
if err ~= nil then if err ~= nil then
return false, nil, nil return false, nil, nil
else
return true, user, pwd
end end
local session_file = conf["session_folder"] .. '/' .. session_id
local session_file_attrs = lfs.attributes(session_file, {"modification"})
if session_file_attrs == nil or math.abs(["modification"] - os.time()) > 3 * 24 * 3600 then
-- session expired
return false, nil, nil
end
return true, user, pwd
end end
-- ########################################################################### -- ###########################################################################