diff --git a/modules/saml2/lib/Auth/Source/SP.php b/modules/saml2/lib/Auth/Source/SP.php index 3af1c5d022880d142b2240f3335d3e07b3a2bc5d..c5730a09e508b35f48b69c41a552ab5384c93055 100644 --- a/modules/saml2/lib/Auth/Source/SP.php +++ b/modules/saml2/lib/Auth/Source/SP.php @@ -155,18 +155,24 @@ class sspmod_saml2_Auth_Source_SP extends SimpleSAML_Auth_Source { assert('is_string($idp)'); assert('is_array($state)'); - $id = SimpleSAML_Auth_State::saveState($state, self::STAGE_SENT); - $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); - $idpMetadata = $metadata->getMetaData($idp, 'saml20-idp-remote'); - $config = SimpleSAML_Configuration::getInstance(); - $sr = new SimpleSAML_XML_SAML20_AuthnRequest($config, $metadata); - $req = $sr->generate($this->entityId, $idpMetadata['SingleSignOnService']); + $spMetadata = $metadata->getMetaDataConfig($this->getEntityId(), 'saml20-sp-hosted'); + $idpMetadata = $metadata->getMetaDataConfig($idp, 'saml20-idp-remote'); - $httpredirect = new SimpleSAML_Bindings_SAML20_HTTPRedirect($config, $metadata); - $httpredirect->sendMessage($req, $this->entityId, $idp, $id); - exit(0); + $ar = sspmod_saml2_Message::buildAuthnRequest($spMetadata, $idpMetadata); + + $ar->setAssertionConsumerServiceURL(SimpleSAML_Module::getModuleURL('saml2/sp/acs.php')); + $ar->setProtocolBinding(SAML2_Const::BINDING_HTTP_POST); + + $id = SimpleSAML_Auth_State::saveState($state, self::STAGE_SENT); + $ar->setRelayState($id); + + $b = new SAML2_HTTPRedirect(); + $b->setDestination(sspmod_SAML2_Message::getDebugDestination()); + $b->send($ar); + + assert('FALSE'); } diff --git a/modules/saml2/lib/Message.php b/modules/saml2/lib/Message.php new file mode 100644 index 0000000000000000000000000000000000000000..fd51160ca047203ff9eb166ed35e1ee9d91d60be --- /dev/null +++ b/modules/saml2/lib/Message.php @@ -0,0 +1,105 @@ +<?php + + +/** + * Common code for building SAML 2 messages based on the + * available metadata. + * + * @package simpleSAMLphp + * @version $Id$ + */ +class sspmod_saml2_Message { + + /** + * Retrieve the destination we should send the message to. + * + * This will return a debug endpoint if we have debug enabled. If debug + * is disabled, NULL is returned, in which case the default destination + * will be used. + * + * @return string|NULL The destination the message should be delivered to. + */ + public static function getDebugDestination() { + + $globalConfig = SimpleSAML_Configuration::getInstance(); + if (!$globalConfig->getValue('debug')) { + return NULL; + } + + return SimpleSAML_Module::getModuleURL('saml2/debug.php'); + } + + + /** + * Add signature key and and senders certificate to message. + * + * @param SAML2_Message $message The message we should add the data to. + * @param SimpleSAML_Configuration $metadata The metadata of the sender. + */ + private static function addSign(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, SAML2_message $message) { + + $signingEnabled = $dstMetadata->getBoolean('redirect.sign', NULL); + if ($signingEnabled === NULL) { + $signingEnabled = $srcMetadata->getBoolean('redirect.sign', FALSE); + } + if (!$signingEnabled) { + return; + } + + + $srcMetadata = $srcMetadata->toArray(); + + $keyArray = SimpleSAML_Utilities::loadPrivateKey($srcMetadata, TRUE); + $certArray = SimpleSAML_Utilities::loadPublicKey($srcMetadata, FALSE); + + $privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); + if (array_key_exists('password', $keyArray)) { + $privateKey->passphrase = $keyArray['password']; + } + $privateKey->loadKey($keyArray['PEM'], FALSE); + + $message->setSignatureKey($privateKey); + + if ($certArray === NULL) { + /* We don't have a certificate to add. */ + return; + } + + if (!array_key_exists('PEM', $certArray)) { + /* We have a public key with only a fingerprint. */ + return; + } + + $message->setCertificates(array($certArray['PEM'])); + } + + + /** + * Build an authentication request based on information in the metadata. + * + * @param SimpleSAML_Configuration $spMetadata The metadata of the service provider. + * @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider. + */ + public static function buildAuthnRequest(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata) { + + $ar = new SAML2_AuthnRequest(); + + $ar->setNameIdPolicy(array( + 'Format' => $spMetadata->getString('NameIDFormat', SAML2_Const::NAMEID_TRANSIENT), + 'AllowCreate' => TRUE, + )); + + $ar->setIssuer($spMetadata->getString('entityid')); + $ar->setDestination($idpMetadata->getString('SingleSignOnService')); + + $ar->setForceAuthn($spMetadata->getBoolean('ForceAuthn', FALSE)); + $ar->setIsPassive($spMetadata->getBoolean('IsPassive', FALSE)); + + self::addSign($spMetadata, $idpMetadata, $ar); + + return $ar; + } + +} + +?> \ No newline at end of file