Skip to content

Instantly share code, notes, and snippets.

@tiancheng91
Created June 8, 2018 20:37
Show Gist options
  • Save tiancheng91/0dcbafe50d3095cda82294d5148b7f45 to your computer and use it in GitHub Desktop.
Save tiancheng91/0dcbafe50d3095cda82294d5148b7f45 to your computer and use it in GitHub Desktop.
nginx lua
-- This module provides a very simple Cookie based authentication (cache).
-- Note: This module does not do any real authentication, it is only useful for caching
-- authentication results. Say, if you are using nginx-ldap-auth module, you do not wish the
-- server to query ldap for each request, you can cache the authentication result in Cookie.
--
-- There are several options to make the authn stronger.
-- secret_key: a secret_key to protect bad user from forging fake authentication hash.
-- max_age: how long the authn will be valid, in second
-- hash_func: a function receives a string and output a digest string which will be stored
-- in user browser.
-- auth_url_fmt: it is used to jump to real auth method on authn fail.
local secret_key = 'please call simpleauthn.set_secret_key() to change this key!'
local max_age = 60 * 60 * 24
local auth_url_fmt = '/auth/?%s'
local hash_func = ngx.md5
-- TODO local refresh = false
local function set_secret_key (key)
secret_key = key
end
local function set_max_age (age_in_seconds)
max_age = age_in_seconds
end
local function set_auth_url_fmt (fmt)
auth_url_fmt = fmt
end
local function set_hash_func (func)
hash_func = func
end
local function calc_hash(uid, expire, ...)
hashdata = secret_key .. '|' .. uid .. '|' .. expire .. '|'
for _, k in pairs({...}) do
hashdata = hashdata .. k .. '|'
end
return hash_func(hashdata)
end
local function set_cookie (uid, domain, ...)
-- on successfully authenticated, call this function to set cookie
expire = ngx.req.start_time() + max_age
hash = calc_hash(uid, expire, ...)
postfix = "; Domain=" .. domain .. "; Path=/; Max-Age=" .. max_age
ngx.header["Set-Cookie"] = {
"authn_uid=" .. uid .. postfix,
"authn_hash=" .. hash .. postfix,
"authn_expire=" .. expire .. postfix,
}
if ngx.var.arg_next then
return ngx.redirect(ngx.unescape_uri(ngx.var.arg_next), ngx.HTTP_MOVED_TEMPORARILY)
end
end
local function get_uid (...)
-- call this function to get authenticated uid, if not authenticated, return nil
uid = ngx.var.cookie_authn_uid
hash = ngx.var.cookie_authn_hash
expire = ngx.var.cookie_authn_expire
if uid ~= nil and hash ~= nil and expire ~= nil and
ngx.req.start_time() < tonumber(expire) and
hash == calc_hash(uid, expire, ...) then
return uid
end
return nil
end
local function get_current_url ()
-- return the escaped current url, for redirecting
return ngx.escape_uri(ngx.var.scheme .. "://" .. ngx.var.http_host .. ngx.var.request_uri)
end
local function get_auth_url ()
return string.format(auth_url_fmt, "next=" .. get_current_url())
end
local function access (...)
-- do simple authz process, all 'logged in' will be authorized, 'non-logged in' user will
-- be redirected to auth_url.
-- access_by_lua 'simpleauthn.access()';
uid = get_uid(...)
if uid == nil then
ngx.header['Location'] = get_auth_url()
ngx.exit(ngx.HTTP_MOVED_TEMPORARILY)
end
end
local P = {
set_secret_key = set_secret_key,
set_max_age = set_max_age,
set_cookie = set_cookie,
set_auth_url_fmt = set_auth_url_fmt,
set_hash_func = set_hash_func,
get_auth_url = get_auth_url,
get_uid = get_uid,
access = access
}
return P
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment