MERGE_LIVE_SAML

This commit is contained in:
Ubuntu 2026-04-07 09:54:58 +05:30
commit 329e9ca991
7 changed files with 101 additions and 88 deletions

View File

@ -81,5 +81,7 @@ class Acl
'roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID], 'roles' => [ADMIN_ROLE_ID, HEAD_ROLE_ID],
'teams' => [] 'teams' => []
], ],
// ===================== SAML =====================
'#^/saml#' => ['public' => true],
]; ];
} }

View File

@ -66,7 +66,7 @@ class Filters extends BaseConfig
public array $globals = [ public array $globals = [
'before' => [ 'before' => [
'HttpRequestLog' => ['except' => 'cli/*'], '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', 'Cors',
'SecurityInputFilter' => ['except' => ['/client/notification/create','test_mail'] ], 'SecurityInputFilter' => ['except' => ['/client/notification/create','test_mail'] ],
'GlobalPostFileUploadGuard', 'GlobalPostFileUploadGuard',

View File

@ -575,13 +575,12 @@ $routes->group('test',function($routes){
//saml - 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->get('saml/login', 'SamlController::login');
$routes->match(['get', 'post'], 'saml/slo', 'SamlController::slo'); $routes->match(['get', 'post'], 'saml/slo', 'SamlController::slo');
}); // });
$routes->post('saml/acs', 'SamlController::acs'); $routes->post('saml/acs', 'SamlController::acs');
$routes->get('saml/logout', 'SamlController::logout'); $routes->get('saml/logout', 'SamlController::logout');

View File

@ -11,33 +11,7 @@ use OneLogin\Saml2\Settings as SamlSettings;
class SamlController extends BaseController 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 private function loadMergedSettings(): array
{ {
$settings = require APPPATH . 'Libraries/Saml/settings.php'; $settings = require APPPATH . 'Libraries/Saml/settings.php';
@ -46,19 +20,13 @@ class SamlController extends BaseController
return array_merge($settings, $advanced); 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(); $model = new SamlClientModel();
$samlClient = $model->find($samlClientId); $samlClient = $model->where('id', $clientId)->first();
if (! $samlClient) { if (! $samlClient) {
throw new \RuntimeException('Invalid SAML client'); throw new \RuntimeException('Invalid SAML client with ID: ' . $clientId);
} }
$settings = $this->loadMergedSettings(); $settings = $this->loadMergedSettings();
@ -80,7 +48,32 @@ class SamlController extends BaseController
public function login() public function login()
{ {
try { 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) { } catch (\Throwable $e) {
return redirect()->to(site_url('login'))->with('error', $e->getMessage()); return redirect()->to(site_url('login'))->with('error', $e->getMessage());
} }
@ -93,7 +86,12 @@ class SamlController extends BaseController
public function acs() public function acs()
{ {
try { 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) { } catch (\Throwable $e) {
return redirect()->to(site_url('login'))->with('error', $e->getMessage()); return redirect()->to(site_url('login'))->with('error', $e->getMessage());
} }
@ -188,7 +186,12 @@ class SamlController extends BaseController
public function logout() public function logout()
{ {
try { 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); $url = $auth->logout(null, [], null, null, true);
} catch (SamlError $e) { } catch (SamlError $e) {
session()->destroy(); session()->destroy();
@ -208,7 +211,12 @@ class SamlController extends BaseController
public function slo() public function slo()
{ {
try { 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) { } catch (\Throwable $e) {
return redirect()->to(site_url('login')); return redirect()->to(site_url('login'));
} }

View File

@ -1,20 +1,23 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE----- -----END CERTIFICATE-----

View File

@ -1,28 +1,28 @@
-----BEGIN PRIVATE KEY----- -----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCSAvTGBbCNuE9f MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDReQDJOCRsMhm5
+ABaPjjPQbh3nPdreWFY9evnCkODaM6uynHJwyYPEvbIVO+fmgq+F+sJnVaunCXw CWlQ1jidn3+XsHOIoWcptGKa6bCR3I/XRx3N6qO+66do54Ms/IkhzOJLeBG7sPBo
QFGgYdUHSBTyWSMIwlBi56Tfi2F+rMxbd2I4kcmu2G91jkBrjDjeYuyH/0EeWgBw Gp1tG0WFqeGX65IRK/5HWjtmynk+wQJZUZ7pM1Ttl+NPiPmW8IiWeg+uyYWJptnH
Pm0bFz7tlxgZy6GTnRYcUaIAsuW1wD7oOuvJiT3DIe/6SXZLgBYOynZ7KPD1LI5A KfAX0LzWfvmG9K3iPALax5doNVc3YAlfZf1m4gBpFUMxOfm2+GDISsrqC7uEXksM
Hw/Nxh7rV9FPvKNrYczPWqVr/P+3+1hsUfwjslrM2fvsSqcbe5OqHoZ6ByYTKpBI f0ifqFuQyD1NPe3Na/64suKnePhqj7aH9kxk9KGLElOUueDSYaB+xQo+qRsWNEdN
gwQgTXCnO3h58Ykf0qSDKm27gz6dHlKNaIU9e4SV3gKPXhY2x/XLLZr/gA7s5vWM rBrhXrA2QOw+nOGGe26OdDLxpWP0tt8iXIlIDVNcxn2pRIxEuEoTg60s5XVvZodu
h7X49aIXAgMBAAECggEAGy8ctk9x3vjNIl9wZVzHQ+MG/pIFSIepNaBXgsTY6/rT sy5kr2qvAgMBAAECggEBAMyqXrM8EJJKTUm2wVjDRiPz8DWkqO2pTeO4pNNZWzTY
3BwJ0lgYWl8b/hE+KbdKv7iBRGF8NXcR4yh+af8846WqbLJmwOc4gymAezQeezCd /Q3JJXzJMl5bX4GnGkq9H7uPtNcqJKFvWyVMQ96T09SqTIokF96BTnwm1H01fUts
vXu9GC4gYAKgwcCxwrQxFEpTokBGNenowf0FYDFUQHTMgmT0mKB68NvL7xhfhxZT R8A/eHW/us4+JlHSspLgx4PHFUWhDsGU7ZmkBzstryQggetza+Xs3pkmhG/EFkg5
P+hdQiCb8cZvGrdmcfUC67hlXSH9ePKQkb8H5e2HULpOiShoZEeoZk+bRq22YewP 3kMLk+OriMOnMMgva1sPm4x9gn7Zo2aK/Zk1tMGq48M+tmno8XpPmDKYG9GLUZ9E
bZ+D0f8Eez5WUSKLRqeasGQvhsAwX491TsP0QeBWILp0KTiKCufuDW9bE1Vvb8h2 pkYvGB7QiiQXERnmzpmHs6K4myd5w+UT5SzDz1dz9HddwBNYzYP0J4z6zwTuSean
xFepUhKvCLT0ZboKhl20K4P6NPOFYaO9Tcr5inTmRQKBgQDEfeSDe5N9563UcLy2 1OHPV7WndN6Zqv6C7Ecw3JmiHNEPqY/wbCI8/SLhZSECgYEA+2DZKct1h9GWfBL/
X325E84xguyEDhyBmrJ3JcmiPnLorSCLaX9CZUi4+BMLN+5bJG7iz4jgfJp/y9ns oTWV2FIamAyis602wFgsUKJIGAGAZgIq6IXChch/bWKBBima7xYzm3drtbZMo7qz
VPPxZyXAJ2RicJkhiLmARWHAo317booyqJDH+/I9gxY5l0fCDMoMLbeEOBsJIlAk khNik1QuODLDvFg17QxoTwl6e45T65jsPVXLkbEwclddahE3sUyzNGlLezWMaFZk
zeTEIIJkr5o2xz+7dLeCdujGDQKBgQC+O05g82tLTLDRliYYvNLlbPf8zgkn8yLx CCz8NtUToLh5O1QQBvVsxi0LGx8CgYEA1VLrU3z6S9N8BoYdERB3nqdh9w/xlU2D
RRkkKO/svXokKLttiwbACuED2eR07seA3AZb1qAdj7V7HBb20axamdtZvKCfHMEw Cb7/U/X5J8T8rl0mzAAdVrDxxCySk/Gq/7tlpl6jTL8kfUD97g7/clINRJZK/gEy
LdZwW1qimIxhkkwGgiBC3bHYvG2BytohU/kQx+0vWFaYOkK8ihsrrrcNILpKjaH2 HORWOOsEMYpP6/gxI8Ddrl0fDSDUnsq28rj3pB0BIzr0Xm3oS/w1U1MrC+LpcJ7K
PV0M4iUDswKBgBY4MkYYDFa5gzO5x+1LoRjzv2Zj6sEII3sYdkP49vMs4qujIEID SS36NHPbTnECgYArcVtWa8EODdyR6L6g35/b2KSb7mMX5jF2IEbYUJNhArFr76f2
nQtyDqY0D1s+aOrPlOZ7F3xjOslm0O7jsG5E/sTa74QePYLIRknWDrbNBhyWJHSU s1cgw7ux7boalIogE5groAHPT4gDK7ro3czFZWDveWZ2YFBBfUlxj1PJkplSOAVr
EUM8H2mLUFEU5V1xOsvjw5PlEFGZGrz+t3biQjyGiwbUw0U8bqAHOE1lAoGAYoZm vC4IKbUTraGJORyE2ZqGzkOrMV/okDWNbCjSWRShTAA3jpmOek+oGBS5RQKBgHZb
3tHUFUjgH3zruE470HWyru2rUlScGWfXUKIfOXcdRpMOF/s0gMxhpFP6/hEZpQTQ 3WmjLBSqMGRGQRZYtqX2ZOp5lCasrQnZST1Ceo1QRIpR8Na7MYwJ/PpFaMZhDel6
CkrL3OOsc9mljyojYT1knUKT0jTbXe+vq7u04petxW83DvvgZ6FY1k8pTFraxP4v Bjo6xAwu+YXta3aMJ7s8P1RQtycbbryNDDHkY51BCnr4Z/tYZSb7T+Eu2AmKm9ss
9mAF2UqgdvFd1TaWQfaYeiUkNy7J3rYDdoO99f8CgYB0GYjD5XzDG4YoftVv4Za5 OWp7FUiAy1khTgPq2YNz36xmp/Luh3n24p37sjBhAoGBAOzA3AEILoL7WqgqXRLd
WPl5MJhiVLuZfvg0aPUkL/J38nQJ66x287wW7aFMr5E86d6QWuVDeE9n3aAnIE8J VDqZ5ZMjmFhKal+ljMgDOEBXjrcg/E6gsHX3PXGaPXEs72UySACcyN6j849ERCE9
NNPpJtFpe3dl/I/XJId0xWiFGyyTz5D7XP9pljlfz6ZV17cZlqvQf6gXg2/ELgtu ikwyRE2FksS4iaUzEsyT7vssM0IqeVa45lO3GYXvD35YznHkXdaZpo4kIqOBF1W0
A8li+XiGe3QPsoZWYZMd4Q== n1Ut6itRUNQIUDuTqNE61n40
-----END PRIVATE KEY----- -----END PRIVATE KEY-----

View File

@ -20,6 +20,7 @@ return [
'entityId' => $base . '/saml/metadata', 'entityId' => $base . '/saml/metadata',
'assertionConsumerService' => [ 'assertionConsumerService' => [
'url' => $base . '/saml/acs', 'url' => $base . '/saml/acs',
// 'url' => 'https://venbait.in/nhance/app/dev/#/login',
'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', 'binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
], ],
'singleLogoutService' => [ 'singleLogoutService' => [