From c61ad23052b92185033ccf40a70d601c5f00d8ee Mon Sep 17 00:00:00 2001 From: Simone Bufarini Date: Tue, 8 Nov 2022 16:28:14 +0100 Subject: [PATCH 1/5] Gestito salvataggio dei log per la richiesta e la risposta durante il login. Gestiti database mySql e SqlServer --- example/index.php | 11 ++- src/Db.php | 135 ++++++++++++++++++++++++++++++ src/Spid/Saml.php | 5 ++ src/Spid/Saml/Idp.php | 6 ++ src/Spid/Saml/In/BaseResponse.php | 8 ++ src/Spid/Saml/Settings.php | 51 ++++++++++- 6 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 src/Db.php diff --git a/example/index.php b/example/index.php index 7c768ee..4fb51a6 100644 --- a/example/index.php +++ b/example/index.php @@ -33,7 +33,16 @@ 'sp_attributeconsumingservice' => [ ["name", "familyName", "fiscalNumber", "email"], ["name", "familyName", "fiscalNumber", "email", "spidCode"] - ] + ], + /*'database' => [ + 'type' => 'mysql', // sqlserver, mysql + 'host' => 'localhost', // database host + 'instance' => '', // database instance + 'name' => 'databaseName', // database name + 'table_name' => 'SPID_LOGS', // table name for logging + 'user' => 'username', // username + 'password' => 'password' // password + ]*/ ]; $sp = new Italia\Spid\Sp($settings); diff --git a/src/Db.php b/src/Db.php new file mode 100644 index 0000000..2a6b6c3 --- /dev/null +++ b/src/Db.php @@ -0,0 +1,135 @@ +idp = $idp; + $this->dbType = $this->idp->sp->settings['database']['type']; + $this->dbHost = $this->idp->sp->settings['database']['host']; + $this->dbInstance = $this->idp->sp->settings['database']['instance']; + $this->dbName = $this->idp->sp->settings['database']['name']; + $this->tableName = $this->idp->sp->settings['database']['table_name']; + $this->dbUser = $this->idp->sp->settings['database']['user']; + $this->dbPassword = $this->idp->sp->settings['database']['password']; + $this->createTableIfNotExist(); + } + + private function createConn() { + if($this->dbType == 'mysql') { + try { + $conn = new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName, $this->dbUser, $this->dbPassword); + $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } catch(PDOException $e) { + $conn = null; + throw new \Exception($e->getMessage()); + } + } + if($this->dbType == 'sqlserver') { + $serverName = $this->dbHost; + if($this->dbInstance) { + $serverName = $serverName."\\".$this->dbInstance; + } + $connectionInfo = array("Database"=>$this->dbName, "UID"=>$this->dbUser, "PWD"=>$this->dbPassword); + $conn = sqlsrv_connect($serverName, $connectionInfo); + } + return $conn; + } + + private function createTableIfNotExist() { + $conn = $this->createConn(); + + if($this->dbType == 'mysql') { + $sql = 'CREATE TABLE IF NOT EXISTS `' . $this->tableName . '` ( `ID` int NOT NULL AUTO_INCREMENT, `AUTHNREQUEST` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, `RESPONSE` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `AUTHNREQ_ID` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `AUTHNREQ_ISSUEINSTANT` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `RESP_ID` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `RESP_ISSUEINSTANT` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `RESP_ISSUER` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `ASSERTION_ID` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `ASSERTION_SUBJECT` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `ASSERTION_SUBJECT_NAMEQUALIFIER` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`ID`)) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; + $conn->exec($sql); + } + + if($this->dbType == 'sqlserver') { + $sql = 'IF NOT EXISTS (SELECT [name] FROM sys.tables where [name] = \'' . $this->tableName . '\') CREATE TABLE ' . $this->tableName . ' ( [ID] [bigint] IDENTITY(1,1) NOT NULL, [AUTHNREQUEST] [nvarchar](max) NOT NULL, [RESPONSE] [nvarchar](max) NULL, [AUTHNREQ_ID] [nvarchar](max) NULL, [AUTHNREQ_ISSUEINSTANT] [nvarchar](max) NULL, [RESP_ID] [nvarchar](max) NULL, [RESP_ISSUEINSTANT] [nvarchar](max) NULL, [RESP_ISSUER] [nvarchar](max) NULL, [ASSERTION_ID] [nvarchar](max) NULL, [ASSERTION_SUBJECT] [nvarchar](max) NULL, [ASSERTION_SUBJECT_NAMEQUALIFIER] [nvarchar](max) NULL) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]'; + $result = sqlsrv_query($conn, $sql); + } + $this->closeConn($conn); + } + + public function insertAuthnDataIntoLog(AuthnRequest $authnReq) { + $conn = $this->createConn(); + $authnReqXML = $authnReq->xml; + $authnReqID = $authnReq->id; + $authnReqIssueIstant = $authnReq->issueInstant; + $assertionID = $this->idp->assertID; + if($this->dbType == 'mysql') { + $sql = "INSERT INTO " . $this->tableName . " (AUTHNREQUEST, AUTHNREQ_ID, AUTHNREQ_ISSUEINSTANT, ASSERTION_ID) VALUES ('".$authnReqXML."', '".$authnReqID."', '".$authnReqIssueIstant."', ".$assertionID.")"; + $conn->exec($sql); + $_SESSION['LogID'] = $conn->lastInsertId(); + } + if($this->dbType == 'sqlserver') { + $query = "INSERT INTO " . $this->tableName . " (AUTHNREQUEST, AUTHNREQ_ID, AUTHNREQ_ISSUEINSTANT, ASSERTION_ID) VALUES (?, ?, ?, ?); SELECT SCOPE_IDENTITY()"; + $params = array($authnReqXML, $authnReqID, $authnReqIssueIstant, $assertionID); + $result = sqlsrv_query($conn, $query, $params); + sqlsrv_next_result($result); + sqlsrv_fetch($result); + $_SESSION['LogID'] = sqlsrv_get_field($result, 0); + } + $this->closeConn($conn); + } + + public function updateLogWithResponseData(BaseResponse $response) { + if(isset($_SESSION['LogID'])) { + $conn = $this->createConn(); + $logID = $_SESSION['LogID']; + $responseXML = $response->getXml(); + if($responseXML) { + $responseXMLString = simplexml_import_dom($responseXML)->asXML(); + $responseID = $responseXML->getAttribute('ID'); + $responseIssueInstant = $responseXML->getAttribute('IssueInstant'); + $responseIssuer = $responseXML->getElementsByTagName('Issuer')->item(0)->nodeValue; + $assertionSubject = simplexml_import_dom($responseXML->getElementsByTagName('Assertion')->item(0)->getElementsByTagName('Subject')->item(0))->asXML(); + $assertionSubjectNameQualifier = $responseXML->getElementsByTagName('Assertion')->item(0)->getElementsByTagName('Subject')->item(0)->getElementsByTagName('NameID')->item(0)->getAttribute('NameQualifier'); + if($this->dbType == 'mysql') { + $sql = "UPDATE " . $this->tableName . " SET RESPONSE = '".$responseXMLString."', RESP_ID = '".$responseID."', RESP_ISSUEINSTANT = '".$responseIssueInstant."', RESP_ISSUER = '".$responseIssuer."', ASSERTION_SUBJECT = '".$assertionSubject."', ASSERTION_SUBJECT_NAMEQUALIFIER = '".$assertionSubjectNameQualifier."' WHERE ID = ".$logID.""; + $conn->exec($sql); + } + if($this->dbType == 'sqlserver') { + $query = "UPDATE " . $this->tableName . " SET RESPONSE = ?, RESP_ID = ?, RESP_ISSUEINSTANT = ?, RESP_ISSUER = ?, ASSERTION_SUBJECT = ?, ASSERTION_SUBJECT_NAMEQUALIFIER = ? WHERE ID = ?"; + $params = array($responseXMLString, $responseID, $responseIssueInstant, $responseIssuer, $assertionSubject, $assertionSubjectNameQualifier, $logID); + $result = sqlsrv_query($conn, $query, $params); + } + } + unset($_SESSION['LogID']); + $this->closeConn($conn); + } + } + + private function closeConn(&$conn) { + if($this->dbType == 'mysql') { + if($conn) { + $conn = null; + } + } + if($this->dbType == 'sqlserver') { + if($conn) { + sqlsrv_close($conn); + } + } + } + +} + +?> \ No newline at end of file diff --git a/src/Spid/Saml.php b/src/Spid/Saml.php index 1fb7d62..dea81fa 100644 --- a/src/Spid/Saml.php +++ b/src/Spid/Saml.php @@ -8,6 +8,7 @@ use Italia\Spid\Spid\Saml\SignatureUtils; use Italia\Spid\Spid\Interfaces\SAMLInterface; use Italia\Spid\Spid\Session; +use Italia\Spid\Db; class Saml implements SAMLInterface { @@ -219,6 +220,10 @@ public function isAuthenticated() : bool $session = new Session($_SESSION['spidSession']); if ($session->isValid()) { $this->session = $session; + if (isset($this->settings['database'])) { + $db = new Db($idp); + $db->updateLogWithResponseData($response); + } return true; } } diff --git a/src/Spid/Saml/Idp.php b/src/Spid/Saml/Idp.php index a4b0327..f456b50 100644 --- a/src/Spid/Saml/Idp.php +++ b/src/Spid/Saml/Idp.php @@ -7,6 +7,7 @@ use Italia\Spid\Spid\Saml\Out\LogoutRequest; use Italia\Spid\Spid\Session; use Italia\Spid\Spid\Saml\Out\LogoutResponse; +use Italia\Spid\Db; class Idp implements IdpInterface { @@ -96,6 +97,11 @@ public function authnRequest($ass, $attr, $binding, $level = 1, $redirectTo = nu $_SESSION['idpEntityId'] = $this->metadata['idpEntityId']; $_SESSION['acsUrl'] = $this->sp->settings['sp_assertionconsumerservice'][$ass]; + if (isset($this->sp->settings['database'])) { + $db = new Db($this); + $db->insertAuthnDataIntoLog($authn); + } + if (!$shouldRedirect || $binding == Settings::BINDING_POST) { return $url; } diff --git a/src/Spid/Saml/In/BaseResponse.php b/src/Spid/Saml/In/BaseResponse.php index e8fb0ff..8963040 100644 --- a/src/Spid/Saml/In/BaseResponse.php +++ b/src/Spid/Saml/In/BaseResponse.php @@ -102,4 +102,12 @@ public function validate($cert) : bool } return $this->response->validate($this->xml, $hasAssertion); } + + public function getXml() { + if($this->xml) { + return $this->xml->getElementsByTagName('Response')->item(0); + } else { + return ''; + } + } } diff --git a/src/Spid/Saml/Settings.php b/src/Spid/Saml/Settings.php index 825aea2..fd9d7cb 100644 --- a/src/Spid/Saml/Settings.php +++ b/src/Spid/Saml/Settings.php @@ -30,7 +30,18 @@ class Settings ] ], 'idp_metadata_folder' => self::REQUIRED, - 'accepted_clock_skew_seconds' => self::NOT_REQUIRED + 'accepted_clock_skew_seconds' => self::NOT_REQUIRED, + 'database' => [ + self::NOT_REQUIRED => [ + 'type' => self::REQUIRED, + 'host' => self::REQUIRED, + 'instance' => self::NOT_REQUIRED, + 'name' => self::REQUIRED, + 'table_name' => self::REQUIRED, + 'user' => self::REQUIRED, + 'password' => self::REQUIRED, + ] + ] ]; private static $validAttributeFields = [ @@ -246,5 +257,43 @@ private static function checkSettingsValues($settings) '"exact", "minimum", "better" or "maximum"'); } } + + if (isset($settings['database'])) { + if (!is_array($settings['database'])) { + throw new \Exception('database should be an array'); + } + foreach ($settings['database'] as $key => $value) { + if (!is_string($value)) { + throw new \Exception( + 'database values should be strings. Valued provided for key ' . $key . + ' is not a string' + ); + } + } + if (isset($settings['database']['type'])) { + if (strcasecmp($settings['database']['type'], "mysql") != 0 && + strcasecmp($settings['database']['type'], "sqlserver") != 0) { + throw new \InvalidArgumentException('type value should be one of:' . + '"mysql", "sqlserver"'); + } + if (!isset($settings['database']['host']) || empty($settings['database']['host'])) { + throw new \Exception('Missing settings field: host'); + } + if (!isset($settings['database']['name']) || empty($settings['database']['name'])) { + throw new \Exception('Missing settings field: name'); + } + if (!isset($settings['database']['table_name']) || empty($settings['database']['table_name'])) { + throw new \Exception('Missing settings field: table_name'); + } + if (!isset($settings['database']['user']) || empty($settings['database']['user'])) { + throw new \Exception('Missing settings field: user'); + } + if (!isset($settings['database']['password']) || empty($settings['database']['password'])) { + throw new \Exception('Missing settings field: password'); + } + } else { + throw new \Exception('Missing settings field: type'); + } + } } } From 97b4589f550821167eed8349e34b37fe2f1d78ba Mon Sep 17 00:00:00 2001 From: Simone Bufarini Date: Wed, 9 Nov 2022 12:54:48 +0100 Subject: [PATCH 2/5] Made the db connection not hardcoded inside the library Provided one connection and usage sample inside the folder "example" --- {src => example/model}/Db.php | 12 ++++++------ example/views/acs.php | 8 ++++++++ example/views/login.php | 9 +++++++++ example/views/login_post.php | 14 +++++++++++++- src/Spid/Saml.php | 14 +++++++------- src/Spid/Saml/Idp.php | 19 +++++++++---------- 6 files changed, 52 insertions(+), 24 deletions(-) rename {src => example/model}/Db.php (97%) diff --git a/src/Db.php b/example/model/Db.php similarity index 97% rename from src/Db.php rename to example/model/Db.php index 2a6b6c3..12f5e1a 100644 --- a/src/Db.php +++ b/example/model/Db.php @@ -1,11 +1,10 @@ idp = $idp; - $this->dbType = $this->idp->sp->settings['database']['type']; + $this->dbType = $this->idp->sp->settings['database']['type']; $this->dbHost = $this->idp->sp->settings['database']['host']; $this->dbInstance = $this->idp->sp->settings['database']['instance']; $this->dbName = $this->idp->sp->settings['database']['name']; @@ -68,8 +67,9 @@ private function createTableIfNotExist() { $this->closeConn($conn); } - public function insertAuthnDataIntoLog(AuthnRequest $authnReq) { + public function insertAuthnDataIntoLog() { $conn = $this->createConn(); + $authnReq = $this->idp->getAuthn(); $authnReqXML = $authnReq->xml; $authnReqID = $authnReq->id; $authnReqIssueIstant = $authnReq->issueInstant; diff --git a/example/views/acs.php b/example/views/acs.php index c4f3eb0..08a10c7 100644 --- a/example/views/acs.php +++ b/example/views/acs.php @@ -1,6 +1,14 @@ isAuthenticated()) { + + if (isset($settings['database']) && !empty($sp->getResponse())) { + $selectedIdp = $_SESSION['idpName'] ?? $_SESSION['spidSession']['idp']; + $db = new Db($sp->getIdp($selectedIdp)); + $db->updateLogWithResponseData($sp->getResponse()); + } + foreach ($sp->getAttributes() as $key => $attr) { echo $key . ' - ' . $attr . '
'; } diff --git a/example/views/login.php b/example/views/login.php index eae8f37..873d77e 100644 --- a/example/views/login.php +++ b/example/views/login.php @@ -1,11 +1,20 @@ login($idp ?? 'testenv', 0, 1, 1, null, true)) { echo "Already logged in !
"; echo "Home"; } else { + if (isset($settings['database'])) { + $db = new Db($sp->getIdp($idp)); + $db->insertAuthnDataIntoLog(); + } echo $url; } diff --git a/example/views/login_post.php b/example/views/login_post.php index 4518a41..1a345f6 100644 --- a/example/views/login_post.php +++ b/example/views/login_post.php @@ -1,8 +1,20 @@ loginPost("testenv", 0, 1, 1, null, true)) { +if (isset($_POST) && isset($_POST['selected_idp'])) { + $idp = $_POST['selected_idp']; +} +if (isset($_GET) && isset($_GET['selected_idp'])) { + $idp = $_GET['selected_idp']; +} + +if (!$url = $sp->loginPost($idp ?? "testenv", 0, 1, 1, null, true)) { echo "Already logged in !
"; echo "Home"; } else { + if (isset($settings['database'])) { + $db = new Db($sp->getIdp($idp)); + $db->insertAuthnDataIntoLog(); + } echo $url; } diff --git a/src/Spid/Saml.php b/src/Spid/Saml.php index dea81fa..10f3645 100644 --- a/src/Spid/Saml.php +++ b/src/Spid/Saml.php @@ -8,13 +8,13 @@ use Italia\Spid\Spid\Saml\SignatureUtils; use Italia\Spid\Spid\Interfaces\SAMLInterface; use Italia\Spid\Spid\Session; -use Italia\Spid\Db; class Saml implements SAMLInterface { public $settings; private $idps = []; // contains filename -> Idp object array private $session; // Session object + private $response; public function __construct(array $settings, $autoconfigure = true) { @@ -208,8 +208,8 @@ public function isAuthenticated() : bool return false; } $idp = $this->loadIdpFromFile($selectedIdp); - $response = new BaseResponse($this); - if (!empty($idp) && !$response->validate($idp->metadata['idpCertValue'])) { + $this->response = new BaseResponse($this); + if (!empty($idp) && !$this->response->validate($idp->metadata['idpCertValue'])) { return false; } if (isset($_SESSION) && isset($_SESSION['inResponseTo'])) { @@ -220,16 +220,16 @@ public function isAuthenticated() : bool $session = new Session($_SESSION['spidSession']); if ($session->isValid()) { $this->session = $session; - if (isset($this->settings['database'])) { - $db = new Db($idp); - $db->updateLogWithResponseData($response); - } return true; } } return false; } + public function getResponse() { + return $this->response; + } + public function logout(int $slo, string $redirectTo = null, $shouldRedirect = true) { $args = func_get_args(); diff --git a/src/Spid/Saml/Idp.php b/src/Spid/Saml/Idp.php index f456b50..567a4f4 100644 --- a/src/Spid/Saml/Idp.php +++ b/src/Spid/Saml/Idp.php @@ -7,7 +7,6 @@ use Italia\Spid\Spid\Saml\Out\LogoutRequest; use Italia\Spid\Spid\Session; use Italia\Spid\Spid\Saml\Out\LogoutResponse; -use Italia\Spid\Db; class Idp implements IdpInterface { @@ -18,6 +17,7 @@ class Idp implements IdpInterface public $attrID; public $level = 1; public $session; + private $authn; public function __construct($sp) { @@ -88,20 +88,15 @@ public function authnRequest($ass, $attr, $binding, $level = 1, $redirectTo = nu $this->attrID = $attr; $this->level = $level; - $authn = new AuthnRequest($this); + $this->authn = new AuthnRequest($this); $url = $binding == Settings::BINDING_REDIRECT ? - $authn->redirectUrl($redirectTo) : - $authn->httpPost($redirectTo); - $_SESSION['RequestID'] = $authn->id; + $this->authn->redirectUrl($redirectTo) : + $this->authn->httpPost($redirectTo); + $_SESSION['RequestID'] = $this->authn->id; $_SESSION['idpName'] = $this->idpFileName; $_SESSION['idpEntityId'] = $this->metadata['idpEntityId']; $_SESSION['acsUrl'] = $this->sp->settings['sp_assertionconsumerservice'][$ass]; - if (isset($this->sp->settings['database'])) { - $db = new Db($this); - $db->insertAuthnDataIntoLog($authn); - } - if (!$shouldRedirect || $binding == Settings::BINDING_POST) { return $url; } @@ -112,6 +107,10 @@ public function authnRequest($ass, $attr, $binding, $level = 1, $redirectTo = nu exit(""); } + public function getAuthn() { + return $this->authn; + } + public function logoutRequest(Session $session, $slo, $binding, $redirectTo = null, $shouldRedirect = true) : string { $this->session = $session; From 5d1fd0f3a1fa3ac3ae8ac40495df709c78e56cc8 Mon Sep 17 00:00:00 2001 From: Simone Bufarini Date: Wed, 9 Nov 2022 14:59:02 +0100 Subject: [PATCH 3/5] Removed the example for the db connection --- example/index.php | 11 +-- example/model/Db.php | 135 ----------------------------------- example/views/acs.php | 8 --- example/views/login.php | 9 --- example/views/login_post.php | 14 +--- src/Spid/Saml/Settings.php | 51 +------------ 6 files changed, 3 insertions(+), 225 deletions(-) delete mode 100644 example/model/Db.php diff --git a/example/index.php b/example/index.php index 4fb51a6..7c768ee 100644 --- a/example/index.php +++ b/example/index.php @@ -33,16 +33,7 @@ 'sp_attributeconsumingservice' => [ ["name", "familyName", "fiscalNumber", "email"], ["name", "familyName", "fiscalNumber", "email", "spidCode"] - ], - /*'database' => [ - 'type' => 'mysql', // sqlserver, mysql - 'host' => 'localhost', // database host - 'instance' => '', // database instance - 'name' => 'databaseName', // database name - 'table_name' => 'SPID_LOGS', // table name for logging - 'user' => 'username', // username - 'password' => 'password' // password - ]*/ + ] ]; $sp = new Italia\Spid\Sp($settings); diff --git a/example/model/Db.php b/example/model/Db.php deleted file mode 100644 index 12f5e1a..0000000 --- a/example/model/Db.php +++ /dev/null @@ -1,135 +0,0 @@ -idp = $idp; - $this->dbType = $this->idp->sp->settings['database']['type']; - $this->dbHost = $this->idp->sp->settings['database']['host']; - $this->dbInstance = $this->idp->sp->settings['database']['instance']; - $this->dbName = $this->idp->sp->settings['database']['name']; - $this->tableName = $this->idp->sp->settings['database']['table_name']; - $this->dbUser = $this->idp->sp->settings['database']['user']; - $this->dbPassword = $this->idp->sp->settings['database']['password']; - $this->createTableIfNotExist(); - } - - private function createConn() { - if($this->dbType == 'mysql') { - try { - $conn = new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName, $this->dbUser, $this->dbPassword); - $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - } catch(PDOException $e) { - $conn = null; - throw new \Exception($e->getMessage()); - } - } - if($this->dbType == 'sqlserver') { - $serverName = $this->dbHost; - if($this->dbInstance) { - $serverName = $serverName."\\".$this->dbInstance; - } - $connectionInfo = array("Database"=>$this->dbName, "UID"=>$this->dbUser, "PWD"=>$this->dbPassword); - $conn = sqlsrv_connect($serverName, $connectionInfo); - } - return $conn; - } - - private function createTableIfNotExist() { - $conn = $this->createConn(); - - if($this->dbType == 'mysql') { - $sql = 'CREATE TABLE IF NOT EXISTS `' . $this->tableName . '` ( `ID` int NOT NULL AUTO_INCREMENT, `AUTHNREQUEST` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, `RESPONSE` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, `AUTHNREQ_ID` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `AUTHNREQ_ISSUEINSTANT` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `RESP_ID` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `RESP_ISSUEINSTANT` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `RESP_ISSUER` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `ASSERTION_ID` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `ASSERTION_SUBJECT` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `ASSERTION_SUBJECT_NAMEQUALIFIER` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`ID`)) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;'; - $conn->exec($sql); - } - - if($this->dbType == 'sqlserver') { - $sql = 'IF NOT EXISTS (SELECT [name] FROM sys.tables where [name] = \'' . $this->tableName . '\') CREATE TABLE ' . $this->tableName . ' ( [ID] [bigint] IDENTITY(1,1) NOT NULL, [AUTHNREQUEST] [nvarchar](max) NOT NULL, [RESPONSE] [nvarchar](max) NULL, [AUTHNREQ_ID] [nvarchar](max) NULL, [AUTHNREQ_ISSUEINSTANT] [nvarchar](max) NULL, [RESP_ID] [nvarchar](max) NULL, [RESP_ISSUEINSTANT] [nvarchar](max) NULL, [RESP_ISSUER] [nvarchar](max) NULL, [ASSERTION_ID] [nvarchar](max) NULL, [ASSERTION_SUBJECT] [nvarchar](max) NULL, [ASSERTION_SUBJECT_NAMEQUALIFIER] [nvarchar](max) NULL) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]'; - $result = sqlsrv_query($conn, $sql); - } - $this->closeConn($conn); - } - - public function insertAuthnDataIntoLog() { - $conn = $this->createConn(); - $authnReq = $this->idp->getAuthn(); - $authnReqXML = $authnReq->xml; - $authnReqID = $authnReq->id; - $authnReqIssueIstant = $authnReq->issueInstant; - $assertionID = $this->idp->assertID; - if($this->dbType == 'mysql') { - $sql = "INSERT INTO " . $this->tableName . " (AUTHNREQUEST, AUTHNREQ_ID, AUTHNREQ_ISSUEINSTANT, ASSERTION_ID) VALUES ('".$authnReqXML."', '".$authnReqID."', '".$authnReqIssueIstant."', ".$assertionID.")"; - $conn->exec($sql); - $_SESSION['LogID'] = $conn->lastInsertId(); - } - if($this->dbType == 'sqlserver') { - $query = "INSERT INTO " . $this->tableName . " (AUTHNREQUEST, AUTHNREQ_ID, AUTHNREQ_ISSUEINSTANT, ASSERTION_ID) VALUES (?, ?, ?, ?); SELECT SCOPE_IDENTITY()"; - $params = array($authnReqXML, $authnReqID, $authnReqIssueIstant, $assertionID); - $result = sqlsrv_query($conn, $query, $params); - sqlsrv_next_result($result); - sqlsrv_fetch($result); - $_SESSION['LogID'] = sqlsrv_get_field($result, 0); - } - $this->closeConn($conn); - } - - public function updateLogWithResponseData(BaseResponse $response) { - if(isset($_SESSION['LogID'])) { - $conn = $this->createConn(); - $logID = $_SESSION['LogID']; - $responseXML = $response->getXml(); - if($responseXML) { - $responseXMLString = simplexml_import_dom($responseXML)->asXML(); - $responseID = $responseXML->getAttribute('ID'); - $responseIssueInstant = $responseXML->getAttribute('IssueInstant'); - $responseIssuer = $responseXML->getElementsByTagName('Issuer')->item(0)->nodeValue; - $assertionSubject = simplexml_import_dom($responseXML->getElementsByTagName('Assertion')->item(0)->getElementsByTagName('Subject')->item(0))->asXML(); - $assertionSubjectNameQualifier = $responseXML->getElementsByTagName('Assertion')->item(0)->getElementsByTagName('Subject')->item(0)->getElementsByTagName('NameID')->item(0)->getAttribute('NameQualifier'); - if($this->dbType == 'mysql') { - $sql = "UPDATE " . $this->tableName . " SET RESPONSE = '".$responseXMLString."', RESP_ID = '".$responseID."', RESP_ISSUEINSTANT = '".$responseIssueInstant."', RESP_ISSUER = '".$responseIssuer."', ASSERTION_SUBJECT = '".$assertionSubject."', ASSERTION_SUBJECT_NAMEQUALIFIER = '".$assertionSubjectNameQualifier."' WHERE ID = ".$logID.""; - $conn->exec($sql); - } - if($this->dbType == 'sqlserver') { - $query = "UPDATE " . $this->tableName . " SET RESPONSE = ?, RESP_ID = ?, RESP_ISSUEINSTANT = ?, RESP_ISSUER = ?, ASSERTION_SUBJECT = ?, ASSERTION_SUBJECT_NAMEQUALIFIER = ? WHERE ID = ?"; - $params = array($responseXMLString, $responseID, $responseIssueInstant, $responseIssuer, $assertionSubject, $assertionSubjectNameQualifier, $logID); - $result = sqlsrv_query($conn, $query, $params); - } - } - unset($_SESSION['LogID']); - $this->closeConn($conn); - } - } - - private function closeConn(&$conn) { - if($this->dbType == 'mysql') { - if($conn) { - $conn = null; - } - } - if($this->dbType == 'sqlserver') { - if($conn) { - sqlsrv_close($conn); - } - } - } - -} - -?> \ No newline at end of file diff --git a/example/views/acs.php b/example/views/acs.php index 08a10c7..c4f3eb0 100644 --- a/example/views/acs.php +++ b/example/views/acs.php @@ -1,14 +1,6 @@ isAuthenticated()) { - - if (isset($settings['database']) && !empty($sp->getResponse())) { - $selectedIdp = $_SESSION['idpName'] ?? $_SESSION['spidSession']['idp']; - $db = new Db($sp->getIdp($selectedIdp)); - $db->updateLogWithResponseData($sp->getResponse()); - } - foreach ($sp->getAttributes() as $key => $attr) { echo $key . ' - ' . $attr . '
'; } diff --git a/example/views/login.php b/example/views/login.php index 873d77e..eae8f37 100644 --- a/example/views/login.php +++ b/example/views/login.php @@ -1,20 +1,11 @@ login($idp ?? 'testenv', 0, 1, 1, null, true)) { echo "Already logged in !
"; echo "Home"; } else { - if (isset($settings['database'])) { - $db = new Db($sp->getIdp($idp)); - $db->insertAuthnDataIntoLog(); - } echo $url; } diff --git a/example/views/login_post.php b/example/views/login_post.php index 1a345f6..4518a41 100644 --- a/example/views/login_post.php +++ b/example/views/login_post.php @@ -1,20 +1,8 @@ loginPost($idp ?? "testenv", 0, 1, 1, null, true)) { +if (!$url = $sp->loginPost("testenv", 0, 1, 1, null, true)) { echo "Already logged in !
"; echo "Home"; } else { - if (isset($settings['database'])) { - $db = new Db($sp->getIdp($idp)); - $db->insertAuthnDataIntoLog(); - } echo $url; } diff --git a/src/Spid/Saml/Settings.php b/src/Spid/Saml/Settings.php index fd9d7cb..825aea2 100644 --- a/src/Spid/Saml/Settings.php +++ b/src/Spid/Saml/Settings.php @@ -30,18 +30,7 @@ class Settings ] ], 'idp_metadata_folder' => self::REQUIRED, - 'accepted_clock_skew_seconds' => self::NOT_REQUIRED, - 'database' => [ - self::NOT_REQUIRED => [ - 'type' => self::REQUIRED, - 'host' => self::REQUIRED, - 'instance' => self::NOT_REQUIRED, - 'name' => self::REQUIRED, - 'table_name' => self::REQUIRED, - 'user' => self::REQUIRED, - 'password' => self::REQUIRED, - ] - ] + 'accepted_clock_skew_seconds' => self::NOT_REQUIRED ]; private static $validAttributeFields = [ @@ -257,43 +246,5 @@ private static function checkSettingsValues($settings) '"exact", "minimum", "better" or "maximum"'); } } - - if (isset($settings['database'])) { - if (!is_array($settings['database'])) { - throw new \Exception('database should be an array'); - } - foreach ($settings['database'] as $key => $value) { - if (!is_string($value)) { - throw new \Exception( - 'database values should be strings. Valued provided for key ' . $key . - ' is not a string' - ); - } - } - if (isset($settings['database']['type'])) { - if (strcasecmp($settings['database']['type'], "mysql") != 0 && - strcasecmp($settings['database']['type'], "sqlserver") != 0) { - throw new \InvalidArgumentException('type value should be one of:' . - '"mysql", "sqlserver"'); - } - if (!isset($settings['database']['host']) || empty($settings['database']['host'])) { - throw new \Exception('Missing settings field: host'); - } - if (!isset($settings['database']['name']) || empty($settings['database']['name'])) { - throw new \Exception('Missing settings field: name'); - } - if (!isset($settings['database']['table_name']) || empty($settings['database']['table_name'])) { - throw new \Exception('Missing settings field: table_name'); - } - if (!isset($settings['database']['user']) || empty($settings['database']['user'])) { - throw new \Exception('Missing settings field: user'); - } - if (!isset($settings['database']['password']) || empty($settings['database']['password'])) { - throw new \Exception('Missing settings field: password'); - } - } else { - throw new \Exception('Missing settings field: type'); - } - } } } From 28ef7721190775a88514013ce6a2c08ff69fb17c Mon Sep 17 00:00:00 2001 From: Simone Bufarini Date: Wed, 9 Nov 2022 15:40:46 +0100 Subject: [PATCH 4/5] Fixed sniff violations on ubuntu --- src/Spid/Saml.php | 3 ++- src/Spid/Saml/Idp.php | 3 ++- src/Spid/Saml/In/BaseResponse.php | 15 ++++++++------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Spid/Saml.php b/src/Spid/Saml.php index 10f3645..57fd63c 100644 --- a/src/Spid/Saml.php +++ b/src/Spid/Saml.php @@ -226,7 +226,8 @@ public function isAuthenticated() : bool return false; } - public function getResponse() { + public function getResponse() + { return $this->response; } diff --git a/src/Spid/Saml/Idp.php b/src/Spid/Saml/Idp.php index 567a4f4..969d5cf 100644 --- a/src/Spid/Saml/Idp.php +++ b/src/Spid/Saml/Idp.php @@ -107,7 +107,8 @@ public function authnRequest($ass, $attr, $binding, $level = 1, $redirectTo = nu exit(""); } - public function getAuthn() { + public function getAuthn() + { return $this->authn; } diff --git a/src/Spid/Saml/In/BaseResponse.php b/src/Spid/Saml/In/BaseResponse.php index 8963040..ae3443c 100644 --- a/src/Spid/Saml/In/BaseResponse.php +++ b/src/Spid/Saml/In/BaseResponse.php @@ -103,11 +103,12 @@ public function validate($cert) : bool return $this->response->validate($this->xml, $hasAssertion); } - public function getXml() { - if($this->xml) { - return $this->xml->getElementsByTagName('Response')->item(0); - } else { - return ''; - } - } + public function getXml() + { + if($this->xml) { + return $this->xml->getElementsByTagName('Response')->item(0); + } else { + return ''; + } + } } From 5c5a2fc2d125e14a4d8cff757e83986f6215de1d Mon Sep 17 00:00:00 2001 From: Simone Bufarini Date: Wed, 9 Nov 2022 17:16:14 +0100 Subject: [PATCH 5/5] Fixed sniff violations on ubuntu pt.2 --- src/Spid/Saml.php | 2 +- src/Spid/Saml/Idp.php | 2 +- src/Spid/Saml/In/BaseResponse.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Spid/Saml.php b/src/Spid/Saml.php index 57fd63c..5b0ac15 100644 --- a/src/Spid/Saml.php +++ b/src/Spid/Saml.php @@ -226,7 +226,7 @@ public function isAuthenticated() : bool return false; } - public function getResponse() + public function getResponse() { return $this->response; } diff --git a/src/Spid/Saml/Idp.php b/src/Spid/Saml/Idp.php index 969d5cf..80fc919 100644 --- a/src/Spid/Saml/Idp.php +++ b/src/Spid/Saml/Idp.php @@ -107,7 +107,7 @@ public function authnRequest($ass, $attr, $binding, $level = 1, $redirectTo = nu exit(""); } - public function getAuthn() + public function getAuthn() { return $this->authn; } diff --git a/src/Spid/Saml/In/BaseResponse.php b/src/Spid/Saml/In/BaseResponse.php index ae3443c..d8b144b 100644 --- a/src/Spid/Saml/In/BaseResponse.php +++ b/src/Spid/Saml/In/BaseResponse.php @@ -105,7 +105,7 @@ public function validate($cert) : bool public function getXml() { - if($this->xml) { + if ($this->xml) { return $this->xml->getElementsByTagName('Response')->item(0); } else { return '';