tstat_be/app/Controllers/SamlController.php

171 lines
5.4 KiB
PHP
Executable File

<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\Controller;
use OneLogin\Saml2\Auth;
use Config\SamlSettings;
use SimpleXMLElement;
class SamlController extends ResourceController
{
protected $format = 'json';
private $auth;
private $settings;
public function __construct()
{
helper('common_helper');
helper('jwt_helper');
$settings = new SamlSettings();
$config = [
'sp' => [
'entityId' => $settings->spEntityId,
'assertionConsumerService' => [
'url' => $settings->spAssertionConsumerServiceUrl,
],
'singleLogoutService' => [
'url' => $settings->spSingleLogoutServiceUrl,
],
'x509cert' => $settings->spCert,
'privateKey' => $settings->spPrivateKey,
],
'idp' => [
'entityId' => $settings->idpEntityId,
'singleSignOnService' => [
'url' => $settings->idpSSOUrl,
],
'singleLogoutService' => [
'url' => $settings->idpSLOUrl,
],
'x509cert' => $settings->idpX509Cert,
],
'security' => [
'authnRequestsSigned' => true,
'logoutRequestSigned' => true,
'wantAssertionsSigned' => true,
'signMetadata' => true, // Ensure metadata is signed
],
];
$this->auth = new Auth($config);
}
public function index()
{
return view('landingpage');
}
// Initiate the SSO (Single Sign-On) process
public function login()
{
$this->auth->login();
}
// Handle the Assertion Consumer Service (ACS) endpoint
public function acs()
{
try {
$this->auth->processResponse();
if ($this->auth->isAuthenticated()) {
$samlUserdata = $this->auth->getAttributes();
$userProfile['samlNameId'] = $this->auth->getNameId();
$userProfile['samlNameIdFormat'] = $this->auth->getNameIdFormat();
$userProfile['samlNameidNameQualifier'] = $this->auth->getNameIdNameQualifier();
$userProfile['samlNameidSPNameQualifier'] = $this->auth->getNameIdSPNameQualifier();
$userProfile['samlSessionIndex'] = $this->auth->getSessionIndex();
$userProfile['displayName'] = $samlUserdata['http://schemas.microsoft.com/identity/claims/displayname'][0] ?? 'Unknown';
$res = checkUserExist($userProfile['displayName'], $userProfile['samlNameId']);
if($res['status'] == true)
{
$token = generateJWT($res['data']);
return $this->respond([ 'status' => 200,'message' => 'Login successful','token' => $token ]);
}else{
return $this->respond([ 'status' => 401,'message' => 'Login Failed','data' => [] ]);
}
} else {
return $this->respond([ 'status' => 401,'message' => 'Unauthorized','data' => [] ]);
}
} catch (\Exception $e) {
return $this->respond([ 'status' => 500,'message' => $e,'data' => [] ]);
}
}
// Handle the Single Logout (SLO) process
public function slo()
{
// $this->auth->logout();
//Check if the user is authenticated using SAML
if ($this->auth->isAuthenticated()) {
// Log out from the SAML session
$this->auth->logout();
return $this->respond([ 'status' => 200,'message' => 'Successfully log out','data' => [] ]);
} else {
// If user is not authenticated, redirect to login
return redirect()->to('/login');
}
}
// Handle the logout response
public function sls()
{
try {
$this->auth->processSLO();
return redirect()->to('/login');
} catch (\Exception $e) {
return redirect()->to('/login');
}
}
public function metadata()
{
try {
// Set the content type to XML
header('Content-Type: application/xml');
// Get the settings from the OneLogin SAML Auth instance
$settings = $this->auth->getSettings();
// Generate SP metadata XML
$metadata = $settings->getSPMetadata();
// Check if there are any errors in the metadata generation
$errors = $settings->validateMetadata($metadata);
if (!empty($errors)) {
// Handle validation errors
throw new \Exception('Invalid SP metadata: ' . implode(', ', $errors));
}
// Output the metadata XML directly
echo $metadata;
} catch (\Exception $e) {
// Handle exceptions and display an appropriate error message
echo "Error generating metadata: " . htmlspecialchars($e->getMessage());
}
}
// Check if the user is authenticated
public function check()
{
if ($this->auth->isAuthenticated()) {
return json_encode($this->auth->getAttributes());
} else {
return json_encode(['status' => 'Not authenticated']);
}
}
}