diff --git a/lib/SimpleSAML/Session.php b/lib/SimpleSAML/Session.php index c40a6c9af2bd17ebbc382ccad7884405cd1196bc..661b38b47573cd4be105a292b8ddfd8393017aa9 100644 --- a/lib/SimpleSAML/Session.php +++ b/lib/SimpleSAML/Session.php @@ -7,11 +7,16 @@ * information about all the currently logged in SPs. This is used when the user initiates a * Single-Log-Out. * + * Bear in mind that the session object implements the Serializable interface, and as such, + * all its contents MUST be serializable. If you need to store something in the session object + * that is not serializable, make sure to convert it first to a representation that can be + * serialized. + * * @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> * @author Jaime Pérez Crespo, UNINETT AS <jaime.perez@uninett.no> * @package SimpleSAMLphp */ -class SimpleSAML_Session +class SimpleSAML_Session implements Serializable { /** @@ -173,6 +178,54 @@ class SimpleSAML_Session } } + + /** + * Serialize this session object. + * + * This method will be invoked by any calls to serialize(). + * + * @return string The serialized representation of this session object. + */ + public function serialize() + { + $serialized = serialize(get_object_vars($this)); + return $serialized; + } + + + /** + * Unserialize a session object and load it.. + * + * This method will be invoked by any calls to unserialize(), allowing us to restore any data that might not + * be serializable in its original form (e.g.: DOM objects). + * + * @param string $serialized The serialized representation of a session that we want to restore. + */ + public function unserialize($serialized) + { + $session = unserialize($serialized); + if (is_array($session)) { + foreach ($session as $k => $v) { + $this->$k = $v; + } + } + + // look for any raw attributes and load them in the 'Attributes' array + foreach ($this->authData as $authority => $parameters) { + if (!array_key_exists('RawAttributes', $parameters)) { + continue; + } + + foreach ($parameters['RawAttributes'] as $attribute => $values) { + foreach ($values as $idx => $value) { // this should be originally a DOMNodeList + /* @var SAML2_XML_saml_AttributeValue $value */ + $this->authData[$authority]['Attributes'][$attribute][$idx] = $value->element->childNodes; + } + } + } + } + + /** * Retrieves the current session. Creates a new session if there's not one. * @@ -542,6 +595,29 @@ class SimpleSAML_Session $data['Expire'] = $maxSessionExpire; } + // check if we have non-serializable attribute values + foreach ($data['Attributes'] as $attribute => $values) { + foreach ($values as $idx => $value) { + if (is_string($value) || is_int($value)) { + continue; + } + + // at this point, this should be a DOMNodeList object... + if (!is_a($value, 'DOMNodeList')) { + continue; + } + + /* @var \DOMNodeList $value */ + if ($value->length === 0) { + continue; + } + + // create an AttributeValue object and save it to 'RawAttributes', using same attribute name and index + $attrval = new SAML2_XML_saml_AttributeValue($value->item(0)->parentNode); + $data['RawAttributes'][$attribute][$idx] = $attrval; + } + } + $this->authData[$authority] = $data; $this->authToken = SimpleSAML\Utils\Random::generateID(); diff --git a/templates/includes/attributes.php b/templates/includes/attributes.php index 2f960c46c0bd2209264b9d1934e2750eeaaf44f5..77f6f06bd4ab1398667ee52ab60bcbc80cb172a9 100644 --- a/templates/includes/attributes.php +++ b/templates/includes/attributes.php @@ -71,6 +71,34 @@ function present_attributes($t, $attributes, $nameParent) { $str .= '</td>'; if ($nameraw === 'jpegPhoto') { $str .= '<td class="attrvalue"><img src="data:image/jpeg;base64,' . htmlspecialchars($value[0]) . '" /></td></tr>'; + } elseif (is_a($value[0], 'DOMNodeList')) { + // try to see if we have a NameID here + $n = $value[0]->length; + for ($idx = 0; $idx < $n; $idx++) { + /* @var DOMNodeList[] $value */ + $elem = $value[0]->item($idx); + /* @var DOMNode $elem */ + if (!($elem->localName === 'NameID' && $elem->namespaceURI === SAML2_Const::NS_SAML)) { + continue; + } + $nameID = new SAML2_XML_saml_NameID($elem); + $eptid = array( + 'NameID' => array($nameID->value), + ); + if (!empty($nameID->Format)) { + $eptid['Format'] = array($nameID->Format); + } + if (!empty($nameID->NameQualifier)) { + $eptid['NameQualifier'] = array($nameID->NameQualifier); + } + if (!empty($nameID->SPNameQualifier)) { + $eptid['SPNameQualifier'] = array($nameID->SPNameQualifier); + } + $str .= '<td class="attrvalue">'; + $str .= present_assoc($eptid); + break; // we only support one NameID here + } + $str .= '</td></tr>'; } else { $str .= '<td class="attrvalue">' . htmlspecialchars($value[0]) . '</td></tr>'; }