Last active
February 23, 2019 18:30
-
-
Save gerardcl/e5455da9014e46558be8a3e8c504a63a to your computer and use it in GitHub Desktop.
Lua Crowd HTTP Auth module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local _M = {} | |
function _M.run () | |
-- grab auth header | |
local auth_header = ngx.req.get_headers().authorization | |
local hWWWAuth = string.format('Basic realm="%s"', os.getenv("CROWD_REALM_NAME")) | |
-- check that the header is present, and if not sead authenticate header | |
if not auth_header or auth_header == '' or not string.match(auth_header, '^[Bb]asic ') then | |
ngx.log(ngx.DEBUG, string.format("no auth header provided --> basic realm set to: %s", hWWWAuth)) | |
ngx.header['WWW-Authenticate'] = hWWWAuth | |
ngx.header.content_type = "text/html" | |
ngx.status = ngx.HTTP_UNAUTHORIZED | |
ngx.say("UNAUTHORIZED") | |
ngx.exit(ngx.HTTP_UNAUTHORIZED) | |
end | |
-- decode authenication header and verify its good | |
local userpass = string.splitBy(ngx.decode_base64(string.splitBy(auth_header, ' ')[2]), ':') | |
if not userpass or #userpass ~= 2 then | |
ngx.log(ngx.ERR, string.format("No auth provided. Bad request.")) | |
ngx.header['WWW-Authenticate'] = hWWWAuth | |
ngx.header.content_type = "text/html" | |
ngx.status = ngx.HTTP_UNAUTHORIZED | |
ngx.say("UNAUTHORIZED") | |
ngx.exit(ngx.HTTP_UNAUTHORIZED) | |
end | |
ngx.log(ngx.DEBUG, string.format("received auth --> %s:**** (length: %s)", userpass[1],table.getn(userpass))) | |
-- authenticate against crowd | |
local http = require("resty.http") -- dependency repo at pintsized/lua-resty-http | |
local httpc = http.new() | |
local path = string.format("/rest/usermanagement/1/authentication?username=%s", userpass[1]) | |
local fullpath = string.format("%s%s", os.getenv("CROWD_URL"), path) | |
local userPass = string.format("%s:%s", os.getenv("CROWD_SERVICE"), os.getenv("CROWD_PASSWORD")) | |
local userPassEnc64 = ngx.encode_base64(userPass) | |
local authBasicHeader = string.format("Basic %s", userPassEnc64) | |
local payload = string.format('{"value":"%s"}', userpass[2]) | |
ngx.log(ngx.DEBUG, string.format("crowd auth --> %s -- auth: %s", fullpath, authBasicHeader)) | |
local res, err = httpc:request_uri(fullpath, { | |
method = "POST", | |
body = payload, | |
headers = { | |
["Authorization"] = authBasicHeader, | |
["Content-Type"] = "application/json", | |
["Accept"] = "application/json", | |
["Content-Length"] = payload:len(), | |
}, | |
keepalive_timeout = 60, | |
keepalive_pool = 10 | |
}) | |
-- error out if not successful | |
if not res then | |
ngx.log(ngx.ERR, string.format("No response. Crowd Auth error: %s", err)) | |
ngx.header['WWW-Authenticate'] = hWWWAuth | |
ngx.header.content_type = "text/html" | |
ngx.status = ngx.HTTP_UNAUTHORIZED | |
ngx.say("UNAUTHORIZED") | |
ngx.exit(ngx.HTTP_UNAUTHORIZED) | |
end | |
if res.status ~= 200 then | |
ngx.log(ngx.ERR, string.format("Crowd Auth error. HTTP status code: %s", res.status)) | |
ngx.header['WWW-Authenticate'] = hWWWAuth | |
ngx.header.content_type = "text/html" | |
ngx.status = ngx.HTTP_UNAUTHORIZED | |
ngx.say("UNAUTHORIZED") | |
ngx.exit(ngx.HTTP_UNAUTHORIZED) | |
end | |
-- no error out, so let's proceed with the proxy | |
ngx.log(ngx.DEBUG, string.format("crowd res --> %s -- err: %s", res.status, err)) | |
end | |
return _M | |
-- splitBy utils method dependency (can be added in the module or through external utils module) | |
function string.splitBy(pString, pPattern) | |
local Table = {} -- NOTE: use {n = 0} in Lua-5.0 | |
local fpat = "(.-)" .. pPattern | |
local last_end = 1 | |
local s, e, cap = pString:find(fpat, 1) | |
while s do | |
if s ~= 1 or cap ~= "" then | |
table.insert(Table,cap) | |
end | |
last_end = e + 1 | |
s, e, cap = pString:find(fpat, last_end) | |
end | |
if last_end <= #pString then | |
cap = pString:sub(last_end) | |
table.insert(Table, cap) | |
end | |
return Table | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- implementation running with OpenResty 1.13.6.x | |
- to load the environment variables inside nginx. Before http-> | |
env CROWD_REALM_NAME; | |
env CROWD_URL; | |
env CROWD_SERVICE; | |
env CROWD_PASSWORD; | |
- to load under http block the Lua required config params in order to assure SSL connections are working. Under http-> | |
lua_ssl_verify_depth 2; | |
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt; # it might change depending on the OS/Distro | |
- to define on access state the auth-crowd module. Under http->server->location-> | |
access_by_lua_block { | |
require("auth-crowd").run() | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment