diff --git a/app/Config/Acl.php b/app/Config/Acl.php index 2dc7b69..0ef07e7 100644 --- a/app/Config/Acl.php +++ b/app/Config/Acl.php @@ -81,5 +81,7 @@ class Acl 'roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID], 'teams' => [] ], + // ===================== SAML ===================== + '#^/saml#' => ['public' => true], ]; } diff --git a/app/Config/Filters.php b/app/Config/Filters.php index 96d34a1..67cae46 100755 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -66,7 +66,7 @@ class Filters extends BaseConfig public array $globals = [ 'before' => [ 'HttpRequestLog' => ['except' => 'cli/*'], - 'AclFilter' => ['except' => ['login', 'logout', 'auth/*', 'oauth2callback','claim-form-download', 'claims-feedback-form', 'autobookstackLogin','/employeeRest/*','processjob', 'getPreEmployeePolicyCount']], + 'AclFilter' => ['except' => ['login', 'logout', 'auth/*', 'oauth2callback','claim-form-download', 'claims-feedback-form', 'autobookstackLogin','/employeeRest/*','processjob', 'getPreEmployeePolicyCount','/saml/*']], 'Cors', 'SecurityInputFilter' => ['except' => ['/client/notification/create','test_mail'] ], 'GlobalPostFileUploadGuard', diff --git a/app/Config/Routes.php b/app/Config/Routes.php index d8b5b98..f3ea69e 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -575,13 +575,12 @@ $routes->group('test',function($routes){ //saml - routes -$routes->group("employeeRest", ['filter' => ['appSignature','AuthApiRateLimitFilter'] ], function ($routes) { +// $routes->group("employeeRest", ['filter' => ['appSignature','AuthApiRateLimitFilter'] ], function ($routes) { - $routes->post('login/start', 'SamlController::startLogin'); $routes->get('saml/login', 'SamlController::login'); $routes->match(['get', 'post'], 'saml/slo', 'SamlController::slo'); -}); +// }); $routes->post('saml/acs', 'SamlController::acs'); $routes->get('saml/logout', 'SamlController::logout'); diff --git a/app/Controllers/SamlController.php b/app/Controllers/SamlController.php index 5c90998..12b4c53 100644 --- a/app/Controllers/SamlController.php +++ b/app/Controllers/SamlController.php @@ -11,33 +11,7 @@ use OneLogin\Saml2\Settings as SamlSettings; class SamlController extends BaseController { - public function startLogin() - { - $email = $this->request->getPost('email'); - - if (! $email) { - return $this->response->setStatusCode(400)->setBody('Email required'); - } - - $email = trim((string) $email); - $at = strrchr($email, '@'); - if ($at === false) { - return $this->response->setStatusCode(400)->setBody('Invalid email'); - } - - $domain = strtolower(substr($at, 1)); - - $model = new SamlClientModel(); - $samlClient = $model->getByDomain($domain); - - if (! $samlClient) { - return $this->response->setStatusCode(404)->setBody('SAML not configured for this domain'); - } - - session()->set('saml_client_id', $samlClient['id']); - - return redirect()->to(site_url('saml/login')); - } + private function loadMergedSettings(): array { $settings = require APPPATH . 'Libraries/Saml/settings.php'; @@ -46,19 +20,13 @@ class SamlController extends BaseController return array_merge($settings, $advanced); } - private function getSamlAuth(): SamlAuth + private function getSamlAuth($clientId): SamlAuth { - $samlClientId = session()->get('saml_client_id'); - - if (! $samlClientId) { - throw new \RuntimeException('SAML client not found in session'); - } - $model = new SamlClientModel(); - $samlClient = $model->find($samlClientId); + $samlClient = $model->where('id', $clientId)->first(); if (! $samlClient) { - throw new \RuntimeException('Invalid SAML client'); + throw new \RuntimeException('Invalid SAML client with ID: ' . $clientId); } $settings = $this->loadMergedSettings(); @@ -80,7 +48,32 @@ class SamlController extends BaseController public function login() { try { - $auth = $this->getSamlAuth(); + + $email = $this->request->getGet('email'); + + if (! $email) { + return $this->response->setStatusCode(400)->setBody('Email required'); + } + + $email = trim((string) $email); + $at = strrchr($email, '@'); + if ($at === false) { + return $this->response->setStatusCode(400)->setBody('Invalid email'); + } + + $domain = strtolower(substr($at, 1)); + + $model = new SamlClientModel(); + $samlClient = $model->getByDomain($domain); + + if (! $samlClient) { + return $this->response->setStatusCode(404)->setBody('SAML not configured for this domain'); + } + + // dd($samlClient); + + $auth = $this->getSamlAuth($samlClient['id']); + } catch (\Throwable $e) { return redirect()->to(site_url('login'))->with('error', $e->getMessage()); } @@ -93,7 +86,12 @@ class SamlController extends BaseController public function acs() { try { - $auth = $this->getSamlAuth(); + $clientId = $this->request->getGet('client_id'); + if (! $clientId) { + return $this->response->setStatusCode(400)->setBody('Client ID required'); + } + + $auth = $this->getSamlAuth($clientId); } catch (\Throwable $e) { return redirect()->to(site_url('login'))->with('error', $e->getMessage()); } @@ -188,7 +186,12 @@ class SamlController extends BaseController public function logout() { try { - $auth = $this->getSamlAuth(); + $clientId = $this->request->getGet('client_id'); + if (! $clientId) { + return $this->response->setStatusCode(400)->setBody('Client ID required'); + } + + $auth = $this->getSamlAuth($clientId); $url = $auth->logout(null, [], null, null, true); } catch (SamlError $e) { session()->destroy(); @@ -208,7 +211,12 @@ class SamlController extends BaseController public function slo() { try { - $auth = $this->getSamlAuth(); + $clientId = $this->request->getGet('client_id'); + if (! $clientId) { + return $this->response->setStatusCode(400)->setBody('Client ID required'); + } + + $auth = $this->getSamlAuth($clientId); } catch (\Throwable $e) { return redirect()->to(site_url('login')); } diff --git a/app/Libraries/Saml/certs/sp.crt b/app/Libraries/Saml/certs/sp.crt index cf723f4..3626dec 100644 --- a/app/Libraries/Saml/certs/sp.crt +++ b/app/Libraries/Saml/certs/sp.crt @@ -1,20 +1,23 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/app/Libraries/Saml/certs/sp.key b/app/Libraries/Saml/certs/sp.key index 5048a20..8913676 100644 --- a/app/Libraries/Saml/certs/sp.key +++ b/app/Libraries/Saml/certs/sp.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCSAvTGBbCNuE9f -+ABaPjjPQbh3nPdreWFY9evnCkODaM6uynHJwyYPEvbIVO+fmgq+F+sJnVaunCXw -QFGgYdUHSBTyWSMIwlBi56Tfi2F+rMxbd2I4kcmu2G91jkBrjDjeYuyH/0EeWgBw -Pm0bFz7tlxgZy6GTnRYcUaIAsuW1wD7oOuvJiT3DIe/6SXZLgBYOynZ7KPD1LI5A -Hw/Nxh7rV9FPvKNrYczPWqVr/P+3+1hsUfwjslrM2fvsSqcbe5OqHoZ6ByYTKpBI -gwQgTXCnO3h58Ykf0qSDKm27gz6dHlKNaIU9e4SV3gKPXhY2x/XLLZr/gA7s5vWM -h7X49aIXAgMBAAECggEAGy8ctk9x3vjNIl9wZVzHQ+MG/pIFSIepNaBXgsTY6/rT -3BwJ0lgYWl8b/hE+KbdKv7iBRGF8NXcR4yh+af8846WqbLJmwOc4gymAezQeezCd -vXu9GC4gYAKgwcCxwrQxFEpTokBGNenowf0FYDFUQHTMgmT0mKB68NvL7xhfhxZT -P+hdQiCb8cZvGrdmcfUC67hlXSH9ePKQkb8H5e2HULpOiShoZEeoZk+bRq22YewP -bZ+D0f8Eez5WUSKLRqeasGQvhsAwX491TsP0QeBWILp0KTiKCufuDW9bE1Vvb8h2 -xFepUhKvCLT0ZboKhl20K4P6NPOFYaO9Tcr5inTmRQKBgQDEfeSDe5N9563UcLy2 -X325E84xguyEDhyBmrJ3JcmiPnLorSCLaX9CZUi4+BMLN+5bJG7iz4jgfJp/y9ns -VPPxZyXAJ2RicJkhiLmARWHAo317booyqJDH+/I9gxY5l0fCDMoMLbeEOBsJIlAk -zeTEIIJkr5o2xz+7dLeCdujGDQKBgQC+O05g82tLTLDRliYYvNLlbPf8zgkn8yLx -RRkkKO/svXokKLttiwbACuED2eR07seA3AZb1qAdj7V7HBb20axamdtZvKCfHMEw -LdZwW1qimIxhkkwGgiBC3bHYvG2BytohU/kQx+0vWFaYOkK8ihsrrrcNILpKjaH2 -PV0M4iUDswKBgBY4MkYYDFa5gzO5x+1LoRjzv2Zj6sEII3sYdkP49vMs4qujIEID -nQtyDqY0D1s+aOrPlOZ7F3xjOslm0O7jsG5E/sTa74QePYLIRknWDrbNBhyWJHSU -EUM8H2mLUFEU5V1xOsvjw5PlEFGZGrz+t3biQjyGiwbUw0U8bqAHOE1lAoGAYoZm -3tHUFUjgH3zruE470HWyru2rUlScGWfXUKIfOXcdRpMOF/s0gMxhpFP6/hEZpQTQ -CkrL3OOsc9mljyojYT1knUKT0jTbXe+vq7u04petxW83DvvgZ6FY1k8pTFraxP4v -9mAF2UqgdvFd1TaWQfaYeiUkNy7J3rYDdoO99f8CgYB0GYjD5XzDG4YoftVv4Za5 -WPl5MJhiVLuZfvg0aPUkL/J38nQJ66x287wW7aFMr5E86d6QWuVDeE9n3aAnIE8J -NNPpJtFpe3dl/I/XJId0xWiFGyyTz5D7XP9pljlfz6ZV17cZlqvQf6gXg2/ELgtu -A8li+XiGe3QPsoZWYZMd4Q== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDReQDJOCRsMhm5 +CWlQ1jidn3+XsHOIoWcptGKa6bCR3I/XRx3N6qO+66do54Ms/IkhzOJLeBG7sPBo +Gp1tG0WFqeGX65IRK/5HWjtmynk+wQJZUZ7pM1Ttl+NPiPmW8IiWeg+uyYWJptnH +KfAX0LzWfvmG9K3iPALax5doNVc3YAlfZf1m4gBpFUMxOfm2+GDISsrqC7uEXksM +f0ifqFuQyD1NPe3Na/64suKnePhqj7aH9kxk9KGLElOUueDSYaB+xQo+qRsWNEdN +rBrhXrA2QOw+nOGGe26OdDLxpWP0tt8iXIlIDVNcxn2pRIxEuEoTg60s5XVvZodu +sy5kr2qvAgMBAAECggEBAMyqXrM8EJJKTUm2wVjDRiPz8DWkqO2pTeO4pNNZWzTY +/Q3JJXzJMl5bX4GnGkq9H7uPtNcqJKFvWyVMQ96T09SqTIokF96BTnwm1H01fUts +R8A/eHW/us4+JlHSspLgx4PHFUWhDsGU7ZmkBzstryQggetza+Xs3pkmhG/EFkg5 +3kMLk+OriMOnMMgva1sPm4x9gn7Zo2aK/Zk1tMGq48M+tmno8XpPmDKYG9GLUZ9E +pkYvGB7QiiQXERnmzpmHs6K4myd5w+UT5SzDz1dz9HddwBNYzYP0J4z6zwTuSean +1OHPV7WndN6Zqv6C7Ecw3JmiHNEPqY/wbCI8/SLhZSECgYEA+2DZKct1h9GWfBL/ +oTWV2FIamAyis602wFgsUKJIGAGAZgIq6IXChch/bWKBBima7xYzm3drtbZMo7qz +khNik1QuODLDvFg17QxoTwl6e45T65jsPVXLkbEwclddahE3sUyzNGlLezWMaFZk +CCz8NtUToLh5O1QQBvVsxi0LGx8CgYEA1VLrU3z6S9N8BoYdERB3nqdh9w/xlU2D +Cb7/U/X5J8T8rl0mzAAdVrDxxCySk/Gq/7tlpl6jTL8kfUD97g7/clINRJZK/gEy +HORWOOsEMYpP6/gxI8Ddrl0fDSDUnsq28rj3pB0BIzr0Xm3oS/w1U1MrC+LpcJ7K +SS36NHPbTnECgYArcVtWa8EODdyR6L6g35/b2KSb7mMX5jF2IEbYUJNhArFr76f2 +s1cgw7ux7boalIogE5groAHPT4gDK7ro3czFZWDveWZ2YFBBfUlxj1PJkplSOAVr +vC4IKbUTraGJORyE2ZqGzkOrMV/okDWNbCjSWRShTAA3jpmOek+oGBS5RQKBgHZb +3WmjLBSqMGRGQRZYtqX2ZOp5lCasrQnZST1Ceo1QRIpR8Na7MYwJ/PpFaMZhDel6 +Bjo6xAwu+YXta3aMJ7s8P1RQtycbbryNDDHkY51BCnr4Z/tYZSb7T+Eu2AmKm9ss +OWp7FUiAy1khTgPq2YNz36xmp/Luh3n24p37sjBhAoGBAOzA3AEILoL7WqgqXRLd +VDqZ5ZMjmFhKal+ljMgDOEBXjrcg/E6gsHX3PXGaPXEs72UySACcyN6j849ERCE9 +ikwyRE2FksS4iaUzEsyT7vssM0IqeVa45lO3GYXvD35YznHkXdaZpo4kIqOBF1W0 +n1Ut6itRUNQIUDuTqNE61n40 -----END PRIVATE KEY----- diff --git a/app/Libraries/Saml/settings.php b/app/Libraries/Saml/settings.php index 7b7e46a..62b8cab 100644 --- a/app/Libraries/Saml/settings.php +++ b/app/Libraries/Saml/settings.php @@ -20,6 +20,7 @@ return [ 'entityId' => $base . '/saml/metadata', 'assertionConsumerService' => [ 'url' => $base . '/saml/acs', + // 'url' => 'https://venbait.in/nhance/app/dev/#/login', 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', ], 'singleLogoutService' => [