/** * Build the request we will send to the IdP. * * @param array $artifacts The artifacts we will request. * @return string The request, as an XML string. */ private static function buildRequest(array $artifacts) { $msg = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' . '<SOAP-ENV:Body>' . '<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"' . ' RequestID="' . SimpleSAML_Utilities::generateID() . '"' . ' MajorVersion="1" MinorVersion="1"' . ' IssueInstant="' . SimpleSAML_Utilities::generateTimestamp() . '"' . '>'; foreach ($artifacts as $a) { $msg .= '<samlp:AssertionArtifact>' . htmlspecialchars($a) . '</samlp:AssertionArtifact>'; } $msg .= '</samlp:Request>' . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>'; return $msg; }
public static function ADFS_GenerateResponse($issuer, $target, $nameid, $attributes) { #$nameid = '*****@*****.**'; $issueInstant = SimpleSAML_Utilities::generateTimestamp(); $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); $assertionID = SimpleSAML_Utilities::generateID(); $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN'; $result = '<wst:RequestSecurityTokenResponse xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"> <wst:RequestedSecurityToken> <saml:Assertion Issuer="' . $issuer . '" IssueInstant="' . $issueInstant . '" AssertionID="' . $assertionID . '" MinorVersion="1" MajorVersion="1" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"> <saml:Conditions NotOnOrAfter="' . $assertionExpire . '" NotBefore="' . $notBefore . '"> <saml:AudienceRestrictionCondition> <saml:Audience>' . $target . '</saml:Audience> </saml:AudienceRestrictionCondition> </saml:Conditions> <saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified" AuthenticationInstant="' . $issueInstant . '"> <saml:Subject> <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> </saml:Subject> </saml:AuthenticationStatement> <saml:AttributeStatement> <saml:Subject> <saml:NameIdentifier Format="' . $nameidFormat . '">' . htmlspecialchars($nameid) . '</saml:NameIdentifier> </saml:Subject>'; foreach ($attributes as $name => $values) { if (!is_array($values) || count($values) == 0) { continue; } $hasValue = FALSE; $r = '<saml:Attribute AttributeNamespace="http://schemas.xmlsoap.org/claims" AttributeName="' . htmlspecialchars($name) . '">'; foreach ($values as $value) { if (!isset($value) or $value === '') { continue; } $r .= '<saml:AttributeValue>' . htmlspecialchars($value) . '</saml:AttributeValue>'; $hasValue = TRUE; } $r .= '</saml:Attribute>'; if ($hasValue) { $result .= $r; } } $result .= ' </saml:AttributeStatement> </saml:Assertion> </wst:RequestedSecurityToken> <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"><wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> <wsa:Address>' . $target . '</wsa:Address> </wsa:EndpointReference></wsp:AppliesTo> </wst:RequestSecurityTokenResponse>'; return $result; }
private function setExpiration($metadata) { if (array_key_exists('expire', $metadata)) { if ($metadata['expire'] - time() < $this->maxDuration) { $this->maxDuration = $metadata['expire'] - time(); } } if ($this->maxCache !== NULL) { $this->entityDescriptor->setAttribute('cacheDuration', 'PT' . $this->maxCache . 'S'); } if ($this->maxDuration !== NULL) { $this->entityDescriptor->setAttribute('validUntil', SimpleSAML_Utilities::generateTimestamp(time() + $this->maxDuration)); } }
/** * Build a authentication response. * * @param array $idp Metadata for the IdP the response is sent from. * @param array $sp Metadata for the SP the response is sent to. * @param string $shire The endpoint on the SP the response is sent to. * @param array|NULL $attributes The attributes which should be included in the response. * @return string The response. */ public function generate(SimpleSAML_Configuration $idp, SimpleSAML_Configuration $sp, $shire, $attributes) { assert('is_string($shire)'); assert('$attributes === NULL || is_array($attributes)'); if ($sp->hasValue('scopedattributes')) { $scopedAttributes = $sp->getArray('scopedattributes'); } elseif ($idp->hasValue('scopedattributes')) { $scopedAttributes = $idp->getArray('scopedattributes'); } else { $scopedAttributes = array(); } $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks. $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); # 5 minutes $assertionid = SimpleSAML_Utilities::generateID(); $spEntityId = $sp->getString('entityid'); $audience = $sp->getString('audience', $spEntityId); $base64 = $sp->getBoolean('base64attributes', FALSE); $namequalifier = $sp->getString('NameQualifier', $spEntityId); $nameid = SimpleSAML_Utilities::generateID(); $subjectNode = '<Subject>' . '<NameIdentifier' . ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' . ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' . '>' . htmlspecialchars($nameid) . '</NameIdentifier>' . '<SubjectConfirmation>' . '<ConfirmationMethod>' . 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . '</ConfirmationMethod>' . '</SubjectConfirmation>' . '</Subject>'; $encodedattributes = ''; if (is_array($attributes)) { $encodedattributes .= '<AttributeStatement>'; $encodedattributes .= $subjectNode; foreach ($attributes as $name => $value) { $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes); } $encodedattributes .= '</AttributeStatement>'; } /* * The SAML 1.1 response message */ $response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant . '" MajorVersion="1" MinorVersion="1" Recipient="' . htmlspecialchars($shire) . '" ResponseID="' . $id . '"> <Status> <StatusCode Value="samlp:Success" /> </Status> <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="' . $assertionid . '" IssueInstant="' . $issueInstant . '" Issuer="' . htmlspecialchars($idp->getString('entityid')) . '" MajorVersion="1" MinorVersion="1"> <Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '"> <AudienceRestrictionCondition> <Audience>' . htmlspecialchars($audience) . '</Audience> </AudienceRestrictionCondition> </Conditions> <AuthenticationStatement AuthenticationInstant="' . $issueInstant . '" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' . $subjectNode . ' </AuthenticationStatement> ' . $encodedattributes . ' </Assertion> </Response>'; return $response; }
/** * Build a authentication response. * * @param array $idp Metadata for the IdP the response is sent from. * @param array $sp Metadata for the SP the response is sent to. * @param string $shire The endpoint on the SP the response is sent to. * @param array|NULL $attributes The attributes which should be included in the response. * @return string The response. */ public function generate($idp, $sp, $shire, $attributes) { assert('is_array($idp)'); assert('is_array($sp)'); assert('is_string($shire)'); assert('$attributes === NULL || is_array($attributes)'); if (array_key_exists('scopedattributes', $sp)) { $scopedAttributes = $sp['scopedattributes']; $scopedAttributesSource = 'the shib13-sp-remote sp \'' . $sp['entityid'] . '\''; } elseif (array_key_exists('scopedattributes', $idp)) { $scopedAttributes = $idp['scopedattributes']; $scopedAttributesSource = 'the shib13-idp-hosted idp \'' . $idp['entityid'] . '\''; } else { $scopedAttributes = array(); } if (!is_array($scopedAttributes)) { throw new Exception('The \'scopedattributes\' option in ' . $scopedAttributesSource . ' should be an array of attribute names.'); } foreach ($scopedAttributes as $an) { if (!is_string($an)) { throw new Exception('Invalid attribute name in the \'scopedattributes\' option in ' . $scopedAttributesSource . ': ' . var_export($an, TRUE)); } } $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks. $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); # 5 minutes $assertionid = SimpleSAML_Utilities::generateID(); $audience = isset($sp['audience']) ? $sp['audience'] : $sp['entityid']; $base64 = isset($sp['base64attributes']) ? $sp['base64attributes'] : false; $namequalifier = isset($sp['NameQualifier']) ? $sp['NameQualifier'] : $sp['entityid']; $nameid = SimpleSAML_Utilities::generateID(); $subjectNode = '<Subject>' . '<NameIdentifier' . ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' . ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' . '>' . htmlspecialchars($nameid) . '</NameIdentifier>' . '<SubjectConfirmation>' . '<ConfirmationMethod>' . 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . '</ConfirmationMethod>' . '</SubjectConfirmation>' . '</Subject>'; $encodedattributes = ''; if (is_array($attributes)) { $encodedattributes .= '<AttributeStatement>'; $encodedattributes .= $subjectNode; foreach ($attributes as $name => $value) { $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes); } $encodedattributes .= '</AttributeStatement>'; } /* * The SAML 1.1 response message */ $response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant . '" MajorVersion="1" MinorVersion="1" Recipient="' . htmlspecialchars($shire) . '" ResponseID="' . $id . '"> <Status> <StatusCode Value="samlp:Success" /> </Status> <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="' . $assertionid . '" IssueInstant="' . $issueInstant . '" Issuer="' . htmlspecialchars($idp['entityid']) . '" MajorVersion="1" MinorVersion="1"> <Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '"> <AudienceRestrictionCondition> <Audience>' . htmlspecialchars($audience) . '</Audience> </AudienceRestrictionCondition> </Conditions> <AuthenticationStatement AuthenticationInstant="' . $issueInstant . '" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' . $subjectNode . ' </AuthenticationStatement> ' . $encodedattributes . ' </Assertion> </Response>'; return $response; }
/** * This function lists all known metadata in the given set. It is returned as an associative array * where the key is the entity id. * * @param $set The set we want to list metadata from. * @return An associative array with the metadata from from the given set. */ public function getList($set = 'saml20-idp-remote') { assert('is_string($set)'); $result = array(); foreach ($this->sources as $source) { $srcList = $source->getMetadataSet($set); foreach ($srcList as $key => $le) { if (array_key_exists('expire', $le)) { if ($le['expire'] < time()) { unset($srcList[$key]); SimpleSAML_Logger::warning("Dropping metadata entity " . var_export($key, true) . ", expired " . SimpleSAML_Utilities::generateTimestamp($le['expire']) . "."); } } } /* $result is the last argument to array_merge because we want the content already * in $result to have precedence. */ $result = array_merge($srcList, $result); } return $result; }
} $ssp_metadata = '// Metadata for state "' . $export_state . '"'; // Generate metadata try { $maxCache = $janus_config->getValue('maxCache', NULL); $maxDuration = $janus_config->getValue('maxDuration', NULL); $entities = $util->getEntitiesByStateType($export_state, $export_type); $xml = new DOMDocument(); $entitiesDescriptor = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:metadata', 'md:EntitiesDescriptor'); $entitiesDescriptorName = $janus_config->getString('export.entitiesDescriptorName', 'Federation'); $entitiesDescriptor->setAttribute('Name', $entitiesDescriptorName); if ($maxCache !== NULL) { $entitiesDescriptor->setAttribute('cacheDuration', 'PT' . $maxCache . 'S'); } if ($maxDuration !== NULL) { $entitiesDescriptor->setAttribute('validUntil', SimpleSAML_Utilities::generateTimestamp(time() + $maxDuration)); } $xml->appendChild($entitiesDescriptor); foreach ($entities as $entity) { $entityDescriptor = sspmod_janus_MetaExport::getXMLMetadata($entity['eid'], $entity['revisionid'], array('maxCache' => $maxCache, 'maxDuration' => $maxDuration)); $ssp_metadata = $ssp_metadata . "\n\n" . sspmod_janus_MetaExport::getFlatMetadata($entity['eid'], $entity['revisionid']); if (empty($entityDescriptor)) { $t = new SimpleSAML_XHTML_Template($config, 'janus:error.php', 'janus:error'); $t->data['header'] = 'JANUS'; $t->data['title'] = 'error_required_metadata_missing_header'; $t->data['error'] = 'error_required_metadata_missing_entity'; $t->data['error_data'] = array('%ENTITY%' => $entity['entityid']); $t->data['extra_data'] = implode("\n", sspmod_janus_MetaExport::getError()); $t->show(); exit(0); }
/** * This function generates an AuthenticationResponse * * @param $idpentityid entityid of IdP * @param $spentityid entityid of SP * @param $inresponseto the ID of the request, that these message is an response to. * @param $nameid the NameID of the user (an array) * @param $attributes A two level array of multivalued attributes, where the first level * index is the attribute name. * * @return AuthenticationResponse as string */ public function generate($idpentityid, $spentityid, $inresponseto, $nameid, $attributes, $status = 'Success') { /** * Retrieving metadata for the two specific entity IDs. */ $idpmd = $this->metadata->getMetaData($idpentityid, 'saml20-idp-hosted'); $spmd = $this->metadata->getMetaData($spentityid, 'saml20-sp-remote'); $issuer = $idpentityid; $destination = $spmd['AssertionConsumerService']; /** * Generating IDs and timestamps. */ $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); $assertionExpire = SimpleSAML_Utilities::generateTimestamp(time() + 60 * 5); # 5 minutes $notBefore = SimpleSAML_Utilities::generateTimestamp(time() - 30); $assertionid = SimpleSAML_Utilities::generateID(); $sessionindex = SimpleSAML_Utilities::generateID(); /** * Handling attributes. */ $base64 = isset($spmd['base64attributes']) ? $spmd['base64attributes'] : false; $nameidformat = isset($spmd['NameIDFormat']) ? $spmd['NameIDFormat'] : 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'; $spnamequalifier = isset($spmd['SPNameQualifier']) ? $spmd['SPNameQualifier'] : $spmd['entityid']; // Attribute Name Format handling. Priority is 1) SP metadata 2) IdP metadata 3) default setting $attributeNameFormat = 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic'; if (isset($spmd['AttributeNameFormat'])) { $attributeNameFormat = $spmd['AttributeNameFormat']; } elseif (isset($idpmd['AttributeNameFormat'])) { $attributeNameFormat = $idpmd['AttributeNameFormat']; } $encodedattributes = ''; foreach ($attributes as $name => $values) { $encodedattributes .= self::enc_attribute($name, $values, $base64, $attributeNameFormat); } $attributestatement = '<saml:AttributeStatement>' . $encodedattributes . '</saml:AttributeStatement>'; $sendattributes = isset($spmd['simplesaml.attributes']) ? $spmd['simplesaml.attributes'] : true; if (!$sendattributes) { $attributestatement = ''; } /** * Handling NameID */ $nameid = null; if ($nameidformat == self::EMAIL) { //print "<pre>SPMD<br>"; //print_r($spmd); //print "<hr>"; //print_r($spmd['simplesaml.nameidattribute']); //print "<hr>ATTRIBUTES<br>"; //print_r($attributes); //print "</pre>"; //print "<hr>"; $nameid = $this->generateNameID($nameidformat, $attributes[$spmd['simplesaml.nameidattribute']][0], $spnamequalifier); } else { $nameid = $this->generateNameID($nameidformat, SimpleSAML_Utilities::generateID(), $spnamequalifier); } $assertion = ""; if ($status === 'Success') { $assertion = '<saml:Assertion Version="2.0" ID="' . $assertionid . '" IssueInstant="' . $issueInstant . '"> <saml:Issuer>' . htmlspecialchars($issuer) . '</saml:Issuer> <saml:Subject> ' . $nameid . ' <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData NotOnOrAfter="' . $assertionExpire . '" InResponseTo="' . htmlspecialchars($inresponseto) . '" Recipient="' . htmlspecialchars($destination) . '"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '"> <saml:AudienceRestriction> <saml:Audience>' . htmlspecialchars($spentityid) . '</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="' . $issueInstant . '" SessionIndex="' . htmlspecialchars($sessionindex) . '"> <saml:AuthnContext> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> ' . $attributestatement . ' </saml:Assertion>'; } /** * Generating the response. */ $authnResponse = '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="' . $id . '" InResponseTo="' . htmlspecialchars($inresponseto) . '" Version="2.0" IssueInstant="' . $issueInstant . '" Destination="' . htmlspecialchars($destination) . '"> <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">' . htmlspecialchars($issuer) . '</saml:Issuer> <samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Value="urn:oasis:names:tc:SAML:2.0:status:' . $status . '" /> </samlp:Status>' . $assertion . '</samlp:Response>'; return $authnResponse; }
/** * Generate a new SAML 2.0 Authentication Request * * @param $spentityid SP Entity ID * @param $destination SingleSignOnService endpoint */ public function generate($spentityid, $destination) { $md = $this->metadata->getMetaData($spentityid); $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); $assertionConsumerServiceURL = $this->metadata->getGenerated('AssertionConsumerService', 'saml20-sp-hosted'); /* * Process the SAML 2.0 SP hosted metadata parameter: NameIDFormat */ $nameidformat = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'; $includeNameIDPolicy = true; if (array_key_exists('NameIDFormat', $md)) { if (is_null($md['NameIDFormat'])) { $includeNameIDPolicy = false; } elseif (!is_string($md['NameIDFormat'])) { throw new Exception('SAML 2.0 SP hosted metadata parameter [NameIDFormat] must be a string.'); } else { $nameidformat = $md['NameIDFormat']; } } if ($includeNameIDPolicy) { $nameIDPolicy = $this->generateNameIDPolicy($nameidformat); } /* * Process the SAML 2.0 SP hosted metadata parameter: ForceAuthn */ $forceauthn = 'false'; if (isset($md['ForceAuthn'])) { if (is_bool($md['ForceAuthn'])) { $forceauthn = $md['ForceAuthn'] ? 'true' : 'false'; } else { throw new Exception('Illegal format of the ForceAuthn parameter in the SAML 2.0 SP hosted metadata for entity [' . $spentityid . ']. This value should be set to a PHP boolean value.'); } } /* * Process the SAML 2.0 SP hosted metadata parameter: AuthnContextClassRef */ $requestauthncontext = ''; if (!empty($md['AuthnContextClassRef'])) { if (!is_string($md['AuthnContextClassRef'])) { throw new Exception('SAML 2.0 SP hosted metadata parameter [AuthnContextClassRef] must be a string.'); } $requestauthncontext = '<samlp:RequestedAuthnContext Comparison="exact"> <saml:AuthnContextClassRef>' . $md['AuthnContextClassRef'] . '</saml:AuthnContextClassRef> </samlp:RequestedAuthnContext>'; } /* Check the metadata for isPassive if $this->isPassive === NULL. */ if ($this->isPassive === NULL) { /* * Process the SAML 2.0 SP hosted metadata parameter: IsPassive */ if (isset($md['IsPassive'])) { if (is_bool($md['IsPassive'])) { $this->isPassive = $md['IsPassive'] ? 'true' : 'false'; } else { throw new Exception('Illegal format of the IsPassive parameter in' . ' the SAML 2.0 SP hosted metadata for entity [' . $spentityid . ']. This value should be set to a PHP boolean value.'); } } else { /* The default is off. */ $this->isPassive = 'false'; } } /* * Create the complete SAML 2.0 Authentication Request */ $authnRequest = '<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="' . $id . '" Version="2.0" IssueInstant="' . $issueInstant . '" ForceAuthn="' . $forceauthn . '" IsPassive="' . $this->isPassive . '" Destination="' . htmlspecialchars($destination) . '" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" AssertionConsumerServiceURL="' . htmlspecialchars($assertionConsumerServiceURL) . '"> <saml:Issuer >' . htmlspecialchars($spentityid) . '</saml:Issuer> ' . $nameIDPolicy . ' ' . $requestauthncontext . ' </samlp:AuthnRequest> '; return $authnRequest; }
public function generate($issuer, $receiver, $nameid, $sessionindex, $mode) { if (!in_array($mode, array('SP', 'IdP'))) { throw new Exception('mode parameter of generate() must be either SP or IdP'); } if ($mode == 'IdP') { $issuerset = 'saml20-idp-hosted'; $receiverset = 'saml20-sp-remote'; } else { $issuerset = 'saml20-sp-hosted'; $receiverset = 'saml20-idp-remote'; } $issuermd = $this->metadata->getMetaData($issuer, $issuerset); $receivermd = $this->metadata->getMetaData($receiver, $receiverset); if ($mode == 'IdP') { $spnamequalifier = isset($receivermd['SPNameQualifier']) ? $receivermd['SPNameQualifier'] : $receivermd['entityid']; } else { $spnamequalifier = isset($issuermd['SPNameQualifier']) ? $issuermd['SPNameQualifier'] : $issuermd['entityid']; } $issueInstant = SimpleSAML_Utilities::generateTimestamp(); $destination = $receivermd['SingleLogoutService']; $logoutRequest = '<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="' . $this->id . '" Version="2.0" Destination="' . htmlspecialchars($destination) . '" IssueInstant="' . $issueInstant . '"> <saml:Issuer >' . htmlspecialchars($issuer) . '</saml:Issuer> <saml:NameID Format="' . htmlspecialchars($nameid['Format']) . '" SPNameQualifier="' . htmlspecialchars($spnamequalifier) . '">' . htmlspecialchars($nameid['value']) . '</saml:NameID> <samlp:SessionIndex>' . htmlspecialchars($sessionindex) . '</samlp:SessionIndex> </samlp:LogoutRequest> '; return $logoutRequest; }
public function generate($issuer, $receiver, $inresponseto, $mode) { if (!in_array($mode, array('SP', 'IdP'))) { throw new Exception('mode parameter of generate() must be either SP or IdP'); } if ($mode == 'IdP') { $issuerset = 'saml20-idp-hosted'; $receiverset = 'saml20-sp-remote'; } else { $issuerset = 'saml20-sp-hosted'; $receiverset = 'saml20-idp-remote'; } //echo 'idp:' . $idpentityid . ' sp:' . $spentityid .' inresponseto:' . $inresponseto . ' namid:' . $nameid; $issuermd = $this->metadata->getMetaData($issuer, $issuerset); $receivermd = $this->metadata->getMetaData($receiver, $receiverset); $id = SimpleSAML_Utilities::generateID(); $issueInstant = SimpleSAML_Utilities::generateTimestamp(); $destination = $receivermd['SingleLogoutService']; $samlResponse = '<samlp:LogoutResponse xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="' . $id . '" Version="2.0" IssueInstant="' . $issueInstant . '" Destination="' . htmlspecialchars($destination) . '" InResponseTo="' . htmlspecialchars($inresponseto) . '"> <saml:Issuer>' . htmlspecialchars($issuer) . '</saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"> </samlp:StatusCode> <samlp:StatusMessage>Successfully logged out from service ' . htmlspecialchars($issuer) . '</samlp:StatusMessage> </samlp:Status> </samlp:LogoutResponse> '; return $samlResponse; }