4 files + 115 − 22 Inline Compare changes Side-by-side Inline Show whitespace changes Files 4 docs/40_Usage/60_Troubleshooting.md +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,24 @@ The generated button is a form with hidden fields. Clicking on the button sends * Go back and reload the page to generate a new button. That one can be clicked. * If it still does not work the clock on your application server or mfa server could be out of sync. ### No MFA appears You didn't get any mfa message, no error and mfa seems to be skipped completely? In the `mfa-ensure.php` enable the last line or put it into your code: ```php echo $mfa->showStatus(); ``` It will show you if a user still has a valid session aftrer a successful challenge or an error was detected like * one of the keys is missing or empty in the config: * 'api' * 'appid' * 'shared_secret' * 'user' ### Debugging There is a debug mode if you want to dive deeper when a behaviour is not like expected. Loading docs/50_Technical_details/mfaclient.class.php.md +43 −3 Original line number Diff line number Diff line ## 📦 Class \mfaclient ```txt /** * * MFA CLIENT CLASS * * Connect a web app with MFA server * * Source: https://git-repo.iml.unibe.ch/iml-open-source/ * Docs: https://os-docs.iml.unibe.ch/mfa-client/index.html * License: GNU GPL 3.0 * */ ``` ## 🔶 Properties Loading @@ -16,12 +26,11 @@ Intialize mfa client - optional set config and user@see setConfig@see setUser **Return**: `` **Parameters**: **2** **Parameters**: **1** | Parameter | Type | Description |-- |-- |-- | \<optional\> $aConfig | `array` | optional: configuration with app id and base url | \<optional\> $sUser | `string` | optional: user id that was logged in ### 🔹 public check() Loading Loading @@ -75,6 +84,24 @@ Get IP of current client (to be sent to MFA server) **Parameters**: **0** ### 🔹 public getConfig() return current config **Return**: `array` **Parameters**: **0** ### 🔹 public getStatus() return current status **Return**: `array` **Parameters**: **0** ### 🔹 public getUrls() get list of urls from MFA server Loading Loading @@ -155,5 +182,18 @@ Show html message and abort to prevent visibility of the app without solved mfa | \<required\> $iHttpStatus | `int` | http statuscode to set | \<required\> $sHtmlcode | `string` | http body to show ### 🔹 public showStatus() show current status if you want to find out why mfa was skipped@example ```txt echo $mfa->showStatus();``` **Return**: `string` **Parameters**: **0** --- Generated with Axels PHP class doc parser. No newline at end of file src/mfa-ensure.php +4 −11 Original line number Diff line number Diff line Loading @@ -3,22 +3,15 @@ * mfa-ensure.php * * @author Axel Hahn <axel.hahn@unibe> * @package IML-Appmonitor * */ if(!($_SERVER['REMOTE_USER']??false)){ return true; } $aConfig = @include "mfaconfig.php"; if(!($aConfig['api']??false)){ return true; } require_once __DIR__.'/mfaclient.class.php'; $mfa = new mfaclient($aConfig, ($_SERVER['REMOTE_USER']??'')); $mfa = new mfaclient(); $mfa->debug($aConfig['debug']??false); $iHttpStatus=$mfa->ensure(); // mfa was skipped? Enable this line to see the reason // echo $mfa->showStatus(); No newline at end of file src/mfaclient.class.php +50 −8 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ class mfaclient protected bool $bDebug = false; protected array $aStatus = []; /** * Intialize mfa client - optional set config and user * Loading @@ -31,17 +33,14 @@ class mfaclient * @see setUser * * @param array $aConfig optional: configuration with app id and base url * @param string $sUser optional: user id that was logged in */ public function __construct(array $aConfig = [], string $sUser = "") public function __construct(array $aConfig = []) { $this->loadConfig(); if ($aConfig) { $this->setConfig($aConfig); } if ($sUser) { $this->setUser($sUser); } $this->setUser($this->aConfig['user']??''); } Loading Loading @@ -235,7 +234,7 @@ class mfaclient ? '' : "<script> window.onload = function() { document.getElementById('$sFormId').submit(); // document.getElementById('$sFormId').submit(); } </script>" ) Loading Loading @@ -285,7 +284,6 @@ class mfaclient if (file_exists($sCfgfile)) { $aTmp = include $sCfgfile; $this->aConfig = $aTmp??[]; $this->setUser($aTmp['user']??''); } } /** Loading Loading @@ -374,11 +372,24 @@ class mfaclient session_start(); } if (($_SESSION['mfa']['user'] ?? '') == $this->sUser) { $this->aStatus[] = 'User still has a valid session after solving a challenge.'; return 200; } else { $this->logout(); } foreach(['api', 'appid', 'shared_secret', 'user'] as $sKey){ if(!isset($this->aConfig[$sKey])){ $this->aStatus[] = "Skip: Key '$sKey' was not set in config."; return 200; } if(!$this->aConfig[$sKey]){ $this->aStatus[] = "Skip: Key '$sKey' is empty in config."; return 200; } } $aMfaReturn = $this->check(); $this->_wd(__METHOD__ . "<br>Http request to mfa api<pre>" . print_r($aMfaReturn, 1) . "</pre>"); $aBody = json_decode($aMfaReturn['response']['body'] ?? '', 1); Loading @@ -405,6 +416,8 @@ class mfaclient ); } $this->aStatus[] = 'User solved the session now.'; $_SESSION['mfa']['user'] = $this->sUser; session_write_close(); Loading Loading @@ -477,6 +490,24 @@ class mfaclient return $ipaddress; } /** * return current config * @return array */ public function getConfig(): array { return $this->aConfig; } /** * return current status * @return array */ public function getStatus(): array { return $this->aStatus; } /** * get list of urls from MFA server * Loading @@ -487,5 +518,16 @@ class mfaclient return $this->_api("urls"); } /** * show current status if you want to find out why mfa was skipped * @example <code>echo $mfa->showStatus();</code> * @return string */ public function showStatus(): string { return 'MFA status: <ul><li>' . implode('</li><li>', $this->aStatus) .'</li></ul>' ; } }
docs/40_Usage/60_Troubleshooting.md +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,24 @@ The generated button is a form with hidden fields. Clicking on the button sends * Go back and reload the page to generate a new button. That one can be clicked. * If it still does not work the clock on your application server or mfa server could be out of sync. ### No MFA appears You didn't get any mfa message, no error and mfa seems to be skipped completely? In the `mfa-ensure.php` enable the last line or put it into your code: ```php echo $mfa->showStatus(); ``` It will show you if a user still has a valid session aftrer a successful challenge or an error was detected like * one of the keys is missing or empty in the config: * 'api' * 'appid' * 'shared_secret' * 'user' ### Debugging There is a debug mode if you want to dive deeper when a behaviour is not like expected. Loading
docs/50_Technical_details/mfaclient.class.php.md +43 −3 Original line number Diff line number Diff line ## 📦 Class \mfaclient ```txt /** * * MFA CLIENT CLASS * * Connect a web app with MFA server * * Source: https://git-repo.iml.unibe.ch/iml-open-source/ * Docs: https://os-docs.iml.unibe.ch/mfa-client/index.html * License: GNU GPL 3.0 * */ ``` ## 🔶 Properties Loading @@ -16,12 +26,11 @@ Intialize mfa client - optional set config and user@see setConfig@see setUser **Return**: `` **Parameters**: **2** **Parameters**: **1** | Parameter | Type | Description |-- |-- |-- | \<optional\> $aConfig | `array` | optional: configuration with app id and base url | \<optional\> $sUser | `string` | optional: user id that was logged in ### 🔹 public check() Loading Loading @@ -75,6 +84,24 @@ Get IP of current client (to be sent to MFA server) **Parameters**: **0** ### 🔹 public getConfig() return current config **Return**: `array` **Parameters**: **0** ### 🔹 public getStatus() return current status **Return**: `array` **Parameters**: **0** ### 🔹 public getUrls() get list of urls from MFA server Loading Loading @@ -155,5 +182,18 @@ Show html message and abort to prevent visibility of the app without solved mfa | \<required\> $iHttpStatus | `int` | http statuscode to set | \<required\> $sHtmlcode | `string` | http body to show ### 🔹 public showStatus() show current status if you want to find out why mfa was skipped@example ```txt echo $mfa->showStatus();``` **Return**: `string` **Parameters**: **0** --- Generated with Axels PHP class doc parser. No newline at end of file
src/mfa-ensure.php +4 −11 Original line number Diff line number Diff line Loading @@ -3,22 +3,15 @@ * mfa-ensure.php * * @author Axel Hahn <axel.hahn@unibe> * @package IML-Appmonitor * */ if(!($_SERVER['REMOTE_USER']??false)){ return true; } $aConfig = @include "mfaconfig.php"; if(!($aConfig['api']??false)){ return true; } require_once __DIR__.'/mfaclient.class.php'; $mfa = new mfaclient($aConfig, ($_SERVER['REMOTE_USER']??'')); $mfa = new mfaclient(); $mfa->debug($aConfig['debug']??false); $iHttpStatus=$mfa->ensure(); // mfa was skipped? Enable this line to see the reason // echo $mfa->showStatus(); No newline at end of file
src/mfaclient.class.php +50 −8 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ class mfaclient protected bool $bDebug = false; protected array $aStatus = []; /** * Intialize mfa client - optional set config and user * Loading @@ -31,17 +33,14 @@ class mfaclient * @see setUser * * @param array $aConfig optional: configuration with app id and base url * @param string $sUser optional: user id that was logged in */ public function __construct(array $aConfig = [], string $sUser = "") public function __construct(array $aConfig = []) { $this->loadConfig(); if ($aConfig) { $this->setConfig($aConfig); } if ($sUser) { $this->setUser($sUser); } $this->setUser($this->aConfig['user']??''); } Loading Loading @@ -235,7 +234,7 @@ class mfaclient ? '' : "<script> window.onload = function() { document.getElementById('$sFormId').submit(); // document.getElementById('$sFormId').submit(); } </script>" ) Loading Loading @@ -285,7 +284,6 @@ class mfaclient if (file_exists($sCfgfile)) { $aTmp = include $sCfgfile; $this->aConfig = $aTmp??[]; $this->setUser($aTmp['user']??''); } } /** Loading Loading @@ -374,11 +372,24 @@ class mfaclient session_start(); } if (($_SESSION['mfa']['user'] ?? '') == $this->sUser) { $this->aStatus[] = 'User still has a valid session after solving a challenge.'; return 200; } else { $this->logout(); } foreach(['api', 'appid', 'shared_secret', 'user'] as $sKey){ if(!isset($this->aConfig[$sKey])){ $this->aStatus[] = "Skip: Key '$sKey' was not set in config."; return 200; } if(!$this->aConfig[$sKey]){ $this->aStatus[] = "Skip: Key '$sKey' is empty in config."; return 200; } } $aMfaReturn = $this->check(); $this->_wd(__METHOD__ . "<br>Http request to mfa api<pre>" . print_r($aMfaReturn, 1) . "</pre>"); $aBody = json_decode($aMfaReturn['response']['body'] ?? '', 1); Loading @@ -405,6 +416,8 @@ class mfaclient ); } $this->aStatus[] = 'User solved the session now.'; $_SESSION['mfa']['user'] = $this->sUser; session_write_close(); Loading Loading @@ -477,6 +490,24 @@ class mfaclient return $ipaddress; } /** * return current config * @return array */ public function getConfig(): array { return $this->aConfig; } /** * return current status * @return array */ public function getStatus(): array { return $this->aStatus; } /** * get list of urls from MFA server * Loading @@ -487,5 +518,16 @@ class mfaclient return $this->_api("urls"); } /** * show current status if you want to find out why mfa was skipped * @example <code>echo $mfa->showStatus();</code> * @return string */ public function showStatus(): string { return 'MFA status: <ul><li>' . implode('</li><li>', $this->aStatus) .'</li></ul>' ; } }