forked from maanas/sso
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Single Sign on Codes and Example
- Loading branch information
Showing
98 changed files
with
16,217 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
server | ||
{ | ||
server_name .maanas.co; | ||
|
||
access_log /home/example/log/agms.maanas.co.access.log; | ||
|
||
error_log /home/example/log/agms.maanas.co.error.log; | ||
|
||
root /home/example/projects; | ||
|
||
index index.php index.html index.htm; | ||
|
||
location / { | ||
} | ||
|
||
location /apps/example { | ||
default_type 'text/plain'; | ||
# Add this to enable SSO on any location | ||
error_page 401 /401; | ||
# Specify the app which validate the access | ||
set $app 'example'; | ||
access_by_lua_file /opt/nginx/conf/sso/sso.lua; | ||
# Any other request parameters | ||
} | ||
|
||
|
||
|
||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
-- login.lua | ||
-- Login Module in Lua | ||
|
||
-- TODO Introduce CSFR token in login form and redirection to basic page, detect json request | ||
|
||
-- This is only a POST Endpoint | ||
if ngx.req.get_method() == "POST" then | ||
|
||
-- Read request body | ||
ngx.req.read_body() | ||
local args = ngx.req.get_post_args() | ||
-- Sanity Check for username and password | ||
if string.match(args["username"],"%W") or string.match(args["password"],"%W") then | ||
-- Improper charactors detected | ||
ngx.exit(ngx.HTTP_BAD_REQUEST) | ||
else | ||
-- Fire the sql to check for | ||
local resp = ngx.location.capture("/sso/login?username="..args['username'].."&hash="..args['password']) | ||
_, _, no, uid, data = string.find(resp.body, [[%[%{"no":(%d+),"uid":(%d+),"data":"([%w ]+)"%}%]%s*]]) | ||
if tonumber(no) == 1 then | ||
-- valid user, Generate a session_token | ||
resp = ngx.location.capture("/sso/token") | ||
_, _, token = string.find(resp.body, [[%[%{"token":"(%w+)"%}%]%s*]]) | ||
|
||
-- Delete all stale session information for this uid | ||
resp = ngx.location.capture("/sso/session/stale?uid="..uid) | ||
_, _, errcode, affected_rows = string.find(resp.body, [[%{"errcode":(%d+),"affected_rows":(%d+)%}%s*]]) | ||
|
||
-- Save token in session | ||
resp = ngx.location.capture("/sso/session/add?token="..token.."&uid="..uid) | ||
_, _, errcode, affected_rows = string.find(resp.body, [[%{"errcode":(%d+),"affected_rows":(%d+)%}%s*]]) | ||
|
||
if tonumber(errcode) == 0 and tonumber(affected_rows) == 1 then | ||
-- Token set in database, set cookiee | ||
local expires = tonumber(ngx.time()) + 3600 | ||
ngx.header["Set-Cookie"] = "uid="..uid..";path=/;domain=.maanas.co;expires="..ngx.cookie_time(expires) | ||
ngx.header["Set-Cookie"] = "session_token="..token..";path=/;domain=.maanas.co;expires="..ngx.cookie_time(expires) | ||
-- Redirect to Incoming Page | ||
if (ngx.var.cookie_AGMSRedirectBack ~= nil) then | ||
return ngx.redirect(ngx.var.cookie_AGMSRedirectBack) | ||
else | ||
return ngx.redirect("http://sso.maanas.co/sso/welcome.html") | ||
end | ||
else | ||
ngx.exit(ngx.HTTP_BAD_REQUEST) | ||
end | ||
else | ||
ngx.exit(ngx.HTTP_UNAUTHORIZED) | ||
end | ||
end | ||
else | ||
ngx.exit(ngx.HTTP_BAD_REQUEST) | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
-- login.lua | ||
-- Login Module in Lua | ||
|
||
-- TODO Introduce CSFR token in login form and redirection to basic page, detect json request | ||
-- Check the session token exist | ||
if ngx.var.cookie_session_token then | ||
-- Sanity Check for session_token | ||
if string.match(ngx.var.cookie_session_token,"%W") then | ||
-- We got a poisioned cookie | ||
ngx.exit(ngx.HTTP_BAD_REQUEST) | ||
else | ||
-- Destroy token in session | ||
ngx.location.capture("/sso/session/delete?token="..ngx.var.cookie_session_token) | ||
-- Delete all cookie | ||
ngx.header["Set-Cookie"] = "uid=deleted;path=/;domain=.maanas.co;expires=Thu, 01-Jan-1970 00:00:01 GMT" | ||
ngx.header["Set-Cookie"] = "session_token=deleted;path=/;domain=.maanas.co;expires=Thu, 01-Jan-1970 00:00:01 GMT" | ||
-- Save the logout URl so that we can come back to this page | ||
ngx.header["Set-Cookie"] = "AGMSRedirectBack=http://"..ngx.var.host..ngx.var.uri..";path=/;domain=.maanas.co;Max-Age=120" | ||
-- Redirect to login form | ||
return ngx.redirect("http://sso.maanas.co/sso") | ||
end | ||
else | ||
return ngx.redirect("http://sso.maanas.co/sso") | ||
|
||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Add this in ngnix.conf inside http {} | ||
# Drizzle sso | ||
upstream sso { | ||
drizzle_server 127.0.0.1:3306 dbname=sso | ||
password=database-password user=sso_dba protocol=mysql; | ||
} | ||
# Load the sso.conf file | ||
include /opt/nginx/conf/sso/sso.conf; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
### Single Sign On Endpoints ### | ||
# Cookie to be valid for whole domain on all sub-domaons # | ||
|
||
|
||
# Token Endpoint to generate session and access token | ||
|
||
location = /sso/token { | ||
internal; # Internal Location Called from sub request only | ||
default_type 'text/plain'; | ||
|
||
set $token_sql 'SELECT SHA2(UUID(), 256) AS token' ; | ||
|
||
drizzle_query $token_sql; | ||
drizzle_pass sso; | ||
|
||
rds_json on; | ||
|
||
drizzle_connect_timeout 500ms; # default 60s | ||
drizzle_send_query_timeout 2s; # default 60s | ||
drizzle_recv_cols_timeout 1s; # default 60s | ||
drizzle_recv_rows_timeout 1s; # default 60s | ||
} | ||
|
||
|
||
location = /sso/session { | ||
internal; # Internal Location Called from sub request only | ||
default_type 'text/plain'; | ||
|
||
set_quote_sql_str $token $cookie_session_token; | ||
set_quote_sql_str $app $arg_app; | ||
set $session_sql 'SELECT 1 AS no, IFNULL(s_uid, 0) AS uid, IFNULL(s_data,"") as data FROM session, app WHERE s_uid = ap_uid AND ap_app = $app AND ap_enabled = 1 AND s_token = $token AND UNIX_TIMESTAMP() - 3600 < s_lastaccess LIMIT 1' ; | ||
|
||
drizzle_query $session_sql; | ||
drizzle_pass sso; | ||
|
||
rds_json on; | ||
|
||
drizzle_connect_timeout 500ms; # default 60s | ||
drizzle_send_query_timeout 2s; # default 60s | ||
drizzle_recv_cols_timeout 1s; # default 60s | ||
drizzle_recv_rows_timeout 1s; # default 60s | ||
|
||
} | ||
|
||
location = /sso/session/add { | ||
internal; # Internal Location Called from sub request only | ||
default_type 'text/plain'; | ||
|
||
set_quote_sql_str $token $arg_token; | ||
set_quote_sql_str $uid $arg_uid; | ||
|
||
set $add_sql 'INSERT INTO session(s_token, s_uid, s_dateadded, s_lastaccess) VALUES ($token, $uid, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())' ; | ||
|
||
drizzle_query $add_sql; | ||
drizzle_pass sso; | ||
|
||
rds_json on; | ||
|
||
drizzle_connect_timeout 500ms; # default 60s | ||
drizzle_send_query_timeout 2s; # default 60s | ||
drizzle_recv_cols_timeout 1s; # default 60s | ||
drizzle_recv_rows_timeout 1s; # default 60s | ||
|
||
} | ||
|
||
location = /sso/session/update { | ||
internal; # Internal Location Called from sub request only | ||
default_type 'text/plain'; | ||
|
||
set_quote_sql_str $token $arg_token; | ||
|
||
set $add_sql 'UPDATE session SET s_lastaccess = UNIX_TIMESTAMP() WHERE s_token = $token' ; | ||
|
||
drizzle_query $add_sql; | ||
drizzle_pass sso; | ||
|
||
rds_json on; | ||
|
||
drizzle_connect_timeout 500ms; # default 60s | ||
drizzle_send_query_timeout 2s; # default 60s | ||
drizzle_recv_cols_timeout 1s; # default 60s | ||
drizzle_recv_rows_timeout 1s; # default 60s | ||
|
||
} | ||
|
||
|
||
location = /sso/session/delete { | ||
internal; # Internal Location Called from sub request only | ||
default_type 'text/plain'; | ||
|
||
set_quote_sql_str $token $arg_token; | ||
|
||
set $delete_sql 'DELETE FROM session WHERE s_token = $token' ; | ||
echo $delete_sql; | ||
drizzle_query $delete_sql; | ||
drizzle_pass sso; | ||
|
||
rds_json on; | ||
|
||
drizzle_connect_timeout 500ms; # default 60s | ||
drizzle_send_query_timeout 2s; # default 60s | ||
drizzle_recv_cols_timeout 1s; # default 60s | ||
drizzle_recv_rows_timeout 1s; # default 60s | ||
|
||
} | ||
|
||
location = /sso/session/stale { | ||
internal; # Internal Location Called from sub request only | ||
default_type 'text/plain'; | ||
|
||
set_quote_sql_str $uid $arg_uid; | ||
|
||
set $delete_sql 'DELETE FROM session WHERE s_uid = $uid AND s_lastaccess < (UNIX_TIMESTAMP() - 7200) '; | ||
|
||
drizzle_query $delete_sql; | ||
drizzle_pass sso; | ||
|
||
rds_json on; | ||
|
||
drizzle_connect_timeout 500ms; # default 60s | ||
drizzle_send_query_timeout 2s; # default 60s | ||
drizzle_recv_cols_timeout 1s; # default 60s | ||
drizzle_recv_rows_timeout 1s; # default 60s | ||
|
||
} | ||
|
||
location = /sso/login { | ||
internal; # Internal Location Called from sub request only | ||
default_type 'text/plain'; | ||
|
||
set_quote_sql_str $username $arg_username; | ||
set_quote_sql_str $hash $arg_hash; | ||
|
||
set $login_sql 'SELECT 1 as no, u_id as uid, CONCAT(u_firstname, " ", u_lastname) as data FROM user WHERE u_username = $username AND u_hash = SHA2($hash, 256) '; | ||
|
||
drizzle_query $login_sql; | ||
drizzle_pass sso; | ||
|
||
rds_json on; | ||
|
||
drizzle_connect_timeout 500ms; # default 60s | ||
drizzle_send_query_timeout 2s; # default 60s | ||
drizzle_recv_cols_timeout 1s; # default 60s | ||
drizzle_recv_rows_timeout 1s; # default 60s | ||
|
||
} | ||
|
||
|
||
### External Locations | ||
|
||
location = /login { | ||
# MIME type determined by default_type: | ||
default_type 'text/plain'; | ||
|
||
access_by_lua_file /opt/nginx/conf/sites-available/sso.maanas.co/login.lua; | ||
|
||
echo 'You are logged in. Please navigate to the resource.'; | ||
} | ||
|
||
location = /logout { | ||
# MIME type determined by default_type: | ||
default_type 'text/plain'; | ||
|
||
access_by_lua_file /opt/nginx/conf/sites-available/sso.maanas.co/logout.lua; | ||
|
||
# Return Success in the end | ||
echo 'OK'; | ||
|
||
} | ||
|
||
## Form Location | ||
|
||
location = /dologin { | ||
rewrite ^.*$ http://sso.maanas.co/sso/index.html break; | ||
#proxy_pass http://sso.maanas.co/sso/index.html; | ||
#proxy_set_header Host 'sso.maanas.co'; | ||
#proxy_set_header X-Real-IP $remote_addr; | ||
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
} | ||
|
||
location = /401 { | ||
rewrite ^.*$ http://sso.maanas.co/sso/unauthorized.html break; | ||
#proxy_pass http://sso.maanas.co/sso/unauthorized.html; | ||
#proxy_set_header Host 'sso.maanas.co'; | ||
#proxy_set_header X-Real-IP $remote_addr; | ||
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
} | ||
|
||
|
||
# Sample Endpoint | ||
location = /apps/default { | ||
# MIME type determined by default_type: | ||
default_type 'text/plain'; | ||
|
||
# Add this to enable SSO on any location | ||
# Specify the app which validate the access | ||
set $app 'default'; | ||
access_by_lua_file /opt/nginx/conf/sites-available/sso.maanas.co/sso.lua; | ||
|
||
# Normal Execution Continues | ||
echo 'OK'; | ||
} | ||
|
||
|
||
# This block will catch static file requests, such as images, css, js | ||
# The ?: prefix is a 'non-capturing' mark, meaning we do not require | ||
# the pattern to be captured into $1 which should help improve performance | ||
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { | ||
# Some basic cache-control for static files to be sent to the browser | ||
expires max; | ||
add_header Pragma public; | ||
add_header Cache-Control "public, must-revalidate, proxy-revalidate"; | ||
} | ||
|
||
# remove the robots line if you want to use wordpress' virtual robots.txt | ||
location = /robots.txt { access_log off; log_not_found off; } | ||
location = /favicon.ico { access_log off; log_not_found off; } | ||
|
||
# this prevents hidden files (beginning with a period) from being served | ||
location ~ /\. { access_log off; log_not_found off; deny all; } | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
-- Single Sign On Module in Lua | ||
-- Check we got a request again a resource | ||
|
||
-- Check we got session_token | ||
if (ngx.var.cookie_session_token == nil or ngx.var.cookie_session_token == "") then | ||
-- Track the endpoint for redirection later | ||
ngx.header["Set-Cookie"] = "MNPLRedirectBack=http://"..ngx.var.host..ngx.var.uri..";path=/;domain=.maanas.co;Max-Age=120" | ||
return ngx.redirect("http://sso.maanas.co/sso") | ||
else | ||
-- Sanity Check for session_token | ||
if string.match(ngx.var.cookie_session_token,"%W") then | ||
-- We got a poisioned cookie | ||
ngx.exit(ngx.HTTP_BAD_REQUEST) | ||
else | ||
if (ngx.var.app == nil or ngx.var.app == "") then | ||
-- We do not got an app match against the authrization | ||
ngx.exit(ngx.HTTP_NOT_FOUND) | ||
end | ||
-- Sanity Check for app is not needed as it is internal request | ||
local resp = ngx.location.capture("/sso/session?app="..ngx.var.app) | ||
if resp.status == 200 then | ||
_, _, no, uid, data = string.find(resp.body, [[%[%{"no":(%d+),"uid":(%d+),"data":"(%w*)"%}%]%s*]]) | ||
if tonumber(no) == 1 then | ||
-- Found valid permission Update lastaccess time stamp and return | ||
-- Update token timestamp in session | ||
ngx.location.capture("/sso/session/update?token="..ngx.var.cookie_session_token) | ||
return | ||
else | ||
ngx.header["Set-Cookie"] = "MNPLRedirectBack=http://"..ngx.var.host..ngx.var.uri..";path=/;domain=.maanas.co;Max-Age=120" | ||
return ngx.redirect("/401") | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.