diff --git a/README.md b/README.md index 22e3d00..c8c5c49 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,12 @@ Forward Authentication for use with proxies (caddy, nginx, traefik, etc) - Edit `include/lucidAuth.config.php.example` to reflect your configuration and save as `include/lucidAuth.config.php` - Create a new website (within any php-capable webserver) and make sure that the documentroot points to the `public` folder - Check if you are able to browse to `https:///lucidAuth.login.php` (where `` is the actual domain -or IP address- your webserver is listening on) -- Edit your proxy to use the new website as forward proxy: -#### in Caddy/nginx -*will come at a later stage* -#### in Traefik -Add the following lines (change to reflect your existing configuration): -``` +- Edit your proxy's configuration to use the new website as forward proxy: + - #### ~~in Caddy/nginx~~ (planned for a later stage) + + - #### in Traefik + Add the following lines (change to reflect your existing configuration): + ``` [frontends.server1] entrypoints = ["https"] backend = "server1" @@ -23,7 +23,10 @@ Add the following lines (change to reflect your existing configuration): [frontends.server1.routes] [frontends.server1.routes.ext] rule = "Host:" -``` + ``` + +- #### Important! + The domainname of the website made in step 3, needs to match the domainname (*ignoring subdomains, if any*) of the resource utilizing this authentication proxy. ## Questions or bugs Feel free to open issues in this repository (or in its mirror on [GitHub](#)). \ No newline at end of file diff --git a/include/lucidAuth.functions.php b/include/lucidAuth.functions.php index fcc7e36..55a626a 100644 --- a/include/lucidAuth.functions.php +++ b/include/lucidAuth.functions.php @@ -98,11 +98,17 @@ function validateToken (string $secureToken) { $jwtPayload = JWT::decode($secureToken, base64_decode($settings->JWT['PrivateKey_base64']), $settings->JWT['Algorithm']); } catch (Exception $e) { // Invalid token + if ($settings->Debug['LogToFile']) { + file_put_contents('../validateToken.log', (new DateTime())->format('Y-m-d\TH:i:s.u') . ' --- Provided token could not be decoded' . PHP_EOL, FILE_APPEND); + } return ['status' => 'Fail', 'reason' => '1']; } if ((int)$jwtPayload->iat < (time() - (int)$settings->Session['Duration'])) { // Expired token + if ($settings->Debug['LogToFile']) { + file_put_contents('../validateToken.log', (new DateTime())->format('Y-m-d\TH:i:s.u') . ' --- Provided token has expired' . PHP_EOL, FILE_APPEND); + } return ['status' => 'Fail', 'reason' => '3']; } @@ -131,6 +137,9 @@ function validateToken (string $secureToken) { })) === 1) { return ['status' => 'Success']; } else { + if ($settings->Debug['LogToFile']) { + file_put_contents('../validateToken.log', (new DateTime())->format('Y-m-d\TH:i:s.u') . ' --- No matching token in database' . PHP_EOL, FILE_APPEND); + } return ['status' => 'Fail', 'reason' => '2']; } } diff --git a/include/lucidAuth.template.php b/include/lucidAuth.template.php index 95bddc7..f0ce42a 100644 --- a/include/lucidAuth.template.php +++ b/include/lucidAuth.template.php @@ -2,7 +2,7 @@ error_reporting(E_ALL & ~E_NOTICE); -$pageLayout = << @@ -19,40 +19,38 @@ $pageLayout = << -
-
+
- -
-
-
-PAGE; +FULL; + +$pageLayout['bare'] = <<<'BARE' + + + + + lucidAuth + + + + + + %1$s + + +BARE; $contentLayout['login'] = << @@ -121,4 +119,5 @@ $contentLayout['dialog'] = << DIALOG; + ?> \ No newline at end of file diff --git a/public/lucidAuth.login.php b/public/lucidAuth.login.php index 43e15b1..062394b 100644 --- a/public/lucidAuth.login.php +++ b/public/lucidAuth.login.php @@ -8,8 +8,33 @@ if ($_POST['do'] == 'login') { $result = authenticateLDAP($_POST['username'], $_POST['password']); if ($result['status'] == 'Success') { + // Store authentication token; in database serverside & in cookie clientside + if (storeToken($result['token'], $settings->LDAP['Domain'] . '\\' . $_POST['username'], $_SERVER['HTTP_HOST'])['status'] !== 'Success') { + // Since this action is only ever called through an AJAX-request; return JSON object + echo '{"Result":"Fail","Reason":"Failed storing authentication token in database and/or cookie"}' . PHP_EOL; + exit; + } + + // Convert base64 encoded string back from JSON; + // forcing it into an associative array (instead of javascript's default StdClass object) + try { + $proxyHeaders = json_decode(base64_decode($_POST['ref']), JSON_OBJECT_AS_ARRAY); + } + catch (Exception $e) { + // Since this action is only ever called through an AJAX-request; return JSON object + echo '{"Result":"Fail","Reason":"Original request URI lost in transition"}' . PHP_EOL; + exit; + } + $originalUri = !empty($proxyHeaders) ? $proxyHeaders['XForwardedProto'] . '://' . $proxyHeaders['XForwardedHost'] . $proxyHeaders['XForwardedUri'] : 'lucidAuth.manage.php'; + // Since this request is only ever called through an AJAX-request; return JSON object - echo sprintf('{"Result":"Success","Location":"%1$s","CrossDomainLogin":%2$s}', $originalUri, $settings->Session['CrossDomainLogin'] ? 'True' : 'False') . PHP_EOL; + header('Content-Type: application/json'); + echo json_encode([ + "Result" => "Success", + "Location" => $originalUri, + "CrossDomainLogin" => $settings->Session['CrossDomainLogin'] + ]); +# echo sprintf('{"Result":"Success","Location":"%1$s","CrossDomainLogin":%2$s}', $originalUri, $settings->Session['CrossDomainLogin'] ? 'True' : 'False') . PHP_EOL; } else { switch ($result['reason']) { case '1': @@ -20,15 +45,9 @@ } } } else { - $stylevar['content']['top'] = '-125px'; - $stylevar['content']['margin-left'] = '-225px'; - $stylevar['content']['height'] = '220px'; - $stylevar['content']['width'] = '450px'; - include_once('../include/lucidAuth.template.php'); - $pageLayout = str_replace('', $contentLayout['login'], $pageLayout); - echo $pageLayout; + echo sprintf($pageLayout['full'], $contentLayout['login']); } ?> \ No newline at end of file diff --git a/public/lucidAuth.setXDomainCookie.php b/public/lucidAuth.setXDomainCookie.php index c951e24..ba423c0 100644 --- a/public/lucidAuth.setXDomainCookie.php +++ b/public/lucidAuth.setXDomainCookie.php @@ -2,17 +2,23 @@ error_reporting(E_ALL ^ E_NOTICE); include_once('../include/lucidAuth.functions.php'); + - // Start with checking $_REQUEST['ref'] - // What do we need? - // token again? + // Start with checking $_REQUEST['ref'] + // What do we need? + // token again? - // approach 1: - // origin domain, so we can intersect with $settings->Session['CookieDomains'] and iterate through the remaining domains, serving them in one page (which contains iframes already) - // this might be slower because it means one additional roundtrip between client and server + // approach 1: + // origin domain, so we can intersect with $settings->Session['CookieDomains'] and iterate through the remaining domains, serving them in one page (which contains iframes already) + // this might be slower because it means one additional roundtrip between client and server - // approach 2: - // let the client setup multiple iframes for all domains other than origin domains - // this requires passing an array of domains to the client in asynchronous reply; which feels insecure + // approach 2: + // let the client setup multiple iframes for all domains other than origin domains + // this requires passing an array of domains to the client in asynchronous reply; which feels insecure + include_once('../include/lucidAuth.template.php'); + + echo sprintf($pageLayout['bare', + '// iFrames go here' + ); ?> \ No newline at end of file diff --git a/public/lucidAuth.validateRequest.php b/public/lucidAuth.validateRequest.php index ee300df..0075d4d 100644 --- a/public/lucidAuth.validateRequest.php +++ b/public/lucidAuth.validateRequest.php @@ -26,7 +26,7 @@ exit; } - if (!empty($_COOKIE['JWT']) && validateToken($_COOKIE['JWT'])['status'] == "Success") { + if (!empty($_COOKIE['JWT']) && validateToken($_COOKIE['JWT'])['status'] === "Success") { // Valid authentication token found header("HTTP/1.1 202 Accepted"); exit; diff --git a/public/misc/script.index.js b/public/misc/script.index.js index d62d6d3..782dcd2 100644 --- a/public/misc/script.index.js +++ b/public/misc/script.index.js @@ -20,27 +20,22 @@ $(document).ready(function(){ ref: $('#ref').val() }) .done(function(data,status) { - try { - var ajaxData = JSON.parse(data); - } - catch (e) { - console.log(data); - } - if (ajaxData.Result === 'Success') { + if (data.Result === 'Success') { $('#btnlogin').css({ 'background': 'green url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAaklEQVQ4jeXOMQ5AQBBG4T2BC4i76EWich7ncAKbqCRuodTqnMNTkFgJs3ZU4tXz/Rlj/hUQv8EpMAClFk9sjUAiHVcCnoFMwhZYgPYG575Xe46aIOyMdJx7ji9GwrEzUgOFCu8DkRp/qxU2BKCUyZR6ygAAAABJRU5ErkJggg==) no-repeat center', 'transform': 'rotateX(0deg)' }); setTimeout(function() { $('#btnlogin').prop('disabled', false).css({ - 'background': '#B50000 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', + 'background': '#003399 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', 'color': '#FFF' }); - if (ajaxData.CrossDomainLogin) { + if (data.CrossDomainLogin) { // Create iframes for other domains console.log('CrossDomainLogin initiated'); } - window.location.replace(ajaxData.Location); +console.log("Navigating to :" + data.Location); + window.location.replace(data.Location); }, 2250); } else { $('#btnlogin').css({ @@ -49,12 +44,12 @@ console.log('CrossDomainLogin initiated'); }); setTimeout(function() { $('#btnlogin').prop('disabled', false).css({ - 'background': '#B50000 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', + 'background': '#003399 linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.25) 51%) no-repeat center', 'color': '#FFF' }); - // TODO: Add feedback (based on ajaxData.Reason) + // TODO: Add feedback (based on data.Reason) // Is the redirect needed? - window.location.replace('lucidAuth.login.php'/*+ '?reason=' + ajaxData.Reason*/); + window.location.replace('lucidAuth.login.php'/*+ '?reason=' + data.Reason*/); }, 2250); } }); diff --git a/public/misc/style.css b/public/misc/style.css index 5de8498..186b31d 100644 --- a/public/misc/style.css +++ b/public/misc/style.css @@ -20,8 +20,7 @@ body { visibility: visible; display: block; } -#content, -#error { +#content { background: url(/images/bg_main_bottom.gif) repeat-x bottom left; font-family: Tahoma, sans-serif; border: 3px solid #CCCCCC; @@ -30,6 +29,10 @@ body { left: 50%; visibility: visible; border-radius: 5px; + top: -125px; + margin-left: -225px; + height: 220px; + width: 450px; } #error .main { padding: 0 10px;