Find the default endpoint of the given type.
public getDefaultEndpoint ( string $endpointType, array $bindings = null, mixed $default = self::REQUIRED_OPTION ) : array | null | ||
$endpointType | string | The endpoint type. |
$bindings | array | Array with acceptable bindings. Can be null if any binding is allowed. |
$default | mixed | The default value to return if no matching endpoint is found. If no default is provided, an exception will be thrown. |
Результат | array | null | The default endpoint, or null if no acceptable endpoints are used. |
/** * This function receives a SAML 1.1 artifact. * * @param SimpleSAML_Configuration $spMetadata The metadata of the SP. * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @return string The <saml1p:Response> element, as an XML string. */ public static function receive(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata) { $artifacts = self::getArtifacts(); $request = self::buildRequest($artifacts); \SimpleSAML\Utils\XML::debugSAMLMessage($request, 'out'); $url = $idpMetadata->getDefaultEndpoint('ArtifactResolutionService', array('urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding')); $url = $url['Location']; $peerPublicKeys = $idpMetadata->getPublicKeys('signing', TRUE); $certData = ''; foreach ($peerPublicKeys as $key) { if ($key['type'] !== 'X509Certificate') { continue; } $certData .= "-----BEGIN CERTIFICATE-----\n" . chunk_split($key['X509Certificate'], 64) . "-----END CERTIFICATE-----\n"; } $file = SimpleSAML\Utils\System::getTempDir() . DIRECTORY_SEPARATOR . sha1($certData) . '.crt'; if (!file_exists($file)) { SimpleSAML\Utils\System::writeFile($file, $certData); } $spKeyCertFile = \SimpleSAML\Utils\Config::getCertPath($spMetadata->getString('privatekey')); $opts = array('ssl' => array('verify_peer' => TRUE, 'cafile' => $file, 'local_cert' => $spKeyCertFile, 'capture_peer_cert' => TRUE, 'capture_peer_chain' => TRUE), 'http' => array('method' => 'POST', 'content' => $request, 'header' => 'SOAPAction: http://www.oasis-open.org/committees/security' . "\r\n" . 'Content-Type: text/xml')); // Fetch the artifact $response = \SimpleSAML\Utils\HTTP::fetch($url, $opts); if ($response === FALSE) { throw new SimpleSAML_Error_Exception('Failed to retrieve assertion from IdP.'); } \SimpleSAML\Utils\XML::debugSAMLMessage($response, 'in'); // Find the response in the SOAP message $response = self::extractResponse($response); return $response; }
/** * Find SP AssertionConsumerService based on parameter in AuthnRequest. * * @param array $supportedBindings The bindings we allow for the response. * @param SimpleSAML_Configuration $spMetadata The metadata for the SP. * @param string|NULL $AssertionConsumerServiceURL AssertionConsumerServiceURL from request. * @param string|NULL $ProtocolBinding ProtocolBinding from request. * @param int|NULL $AssertionConsumerServiceIndex AssertionConsumerServiceIndex from request. * @return array Array with the Location and Binding we should use for the response. */ public static function getAssertionConsumerService(array $supportedBindings, SimpleSAML_Configuration $spMetadata, $AssertionConsumerServiceURL, $ProtocolBinding, $AssertionConsumerServiceIndex) { assert('is_string($AssertionConsumerServiceURL) || is_null($AssertionConsumerServiceURL)'); assert('is_string($ProtocolBinding) || is_null($ProtocolBinding)'); assert('is_int($AssertionConsumerServiceIndex) || is_null($AssertionConsumerServiceIndex)'); /* We want to pick the best matching endpoint in the case where for example * only the ProtocolBinding is given. We therefore pick endpoints with the * following priority: * 1. isDefault="true" * 2. isDefault unset * 3. isDefault="false" */ $firstNotFalse = NULL; $firstFalse = NULL; foreach ($spMetadata->getEndpoints('AssertionConsumerService') as $ep) { if ($AssertionConsumerServiceURL !== NULL && $ep['Location'] !== $AssertionConsumerServiceURL) { continue; } if ($ProtocolBinding !== NULL && $ep['Binding'] !== $ProtocolBinding) { continue; } if ($AssertionConsumerServiceIndex !== NULL && $ep['index'] !== $AssertionConsumerServiceIndex) { continue; } if (!in_array($ep['Binding'], $supportedBindings, TRUE)) { /* The endpoint has an unsupported binding. */ continue; } /* We have an endpoint that matches all our requirements. Check if it is the best one. */ if (array_key_exists('isDefault', $ep)) { if ($ep['isDefault'] === TRUE) { /* This is the first matching endpoint with isDefault set to TRUE. */ return $ep; } /* isDefault is set to FALSE, but the endpoint is still useable. */ if ($firstFalse === NULL) { /* This is the first endpoint that we can use. */ $firstFalse = $ep; } } else { if ($firstNotFalse === NULL) { /* This is the first endpoint without isDefault set. */ $firstNotFalse = $ep; } } } if ($firstNotFalse !== NULL) { return $firstNotFalse; } elseif ($firstFalse !== NULL) { return $firstFalse; } SimpleSAML_Logger::warning('Authentication request specifies invalid AssertionConsumerService:'); if ($AssertionConsumerServiceURL !== NULL) { SimpleSAML_Logger::warning('AssertionConsumerServiceURL: ' . var_export($AssertionConsumerServiceURL, TRUE)); } if ($ProtocolBinding !== NULL) { SimpleSAML_Logger::warning('ProtocolBinding: ' . var_export($ProtocolBinding, TRUE)); } if ($AssertionConsumerServiceIndex !== NULL) { SimpleSAML_Logger::warning('AssertionConsumerServiceIndex: ' . var_export($AssertionConsumerServiceIndex, TRUE)); } /* We have no good endpoints. Our last resort is to just use the default endpoint. */ return $spMetadata->getDefaultEndpoint('AssertionConsumerService', $supportedBindings); }
/** * Build a logout response based on information in the metadata. * * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender. * @param SimpleSAML_Configuration $dstpMetadata The metadata of the recipient. */ public static function buildLogoutResponse(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata) { $dst = $dstMetadata->getDefaultEndpoint('SingleLogoutService', array(SAML2_Const::BINDING_HTTP_REDIRECT)); if (isset($dst['ResponseLocation'])) { $dst = $dst['ResponseLocation']; } else { $dst = $dst['Location']; } $lr = new SAML2_LogoutResponse(); $lr->setIssuer($srcMetadata->getString('entityid')); $lr->setDestination($dst); self::addRedirectSign($srcMetadata, $dstMetadata, $lr); return $lr; }