From d9d1d0fe571004469ca095499ae61d8208389f00 Mon Sep 17 00:00:00 2001 From: Tim van Dijen <tvdijen@gmail.com> Date: Sat, 23 Mar 2019 22:23:11 +0100 Subject: [PATCH] Externalize ADFS module (#1071) --- bin/build-release.sh | 1 + composer.json | 1 + modules/adfs/default-disable | 3 - modules/adfs/docs/adfs.md | 83 ---- modules/adfs/lib/IdP/ADFS.php | 396 ------------------ modules/adfs/lib/SAML2/XML/fed/Constants.php | 17 - modules/adfs/lib/SAML2/XML/fed/Endpoint.php | 38 -- .../XML/fed/SecurityTokenServiceType.php | 84 ---- .../lib/SAML2/XML/fed/TokenTypesOffered.php | 30 -- modules/adfs/templates/generateResponse.twig | 31 -- modules/adfs/templates/postResponse.twig | 16 - modules/adfs/www/assets/js/postResponse.js | 3 - modules/adfs/www/idp/metadata.php | 183 -------- modules/adfs/www/idp/prp.php | 29 -- 14 files changed, 2 insertions(+), 913 deletions(-) delete mode 100644 modules/adfs/default-disable delete mode 100644 modules/adfs/docs/adfs.md delete mode 100644 modules/adfs/lib/IdP/ADFS.php delete mode 100644 modules/adfs/lib/SAML2/XML/fed/Constants.php delete mode 100644 modules/adfs/lib/SAML2/XML/fed/Endpoint.php delete mode 100644 modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php delete mode 100644 modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php delete mode 100644 modules/adfs/templates/generateResponse.twig delete mode 100644 modules/adfs/templates/postResponse.twig delete mode 100644 modules/adfs/www/assets/js/postResponse.js delete mode 100644 modules/adfs/www/idp/metadata.php delete mode 100644 modules/adfs/www/idp/prp.php diff --git a/bin/build-release.sh b/bin/build-release.sh index b399c54d7..738bc0003 100755 --- a/bin/build-release.sh +++ b/bin/build-release.sh @@ -47,6 +47,7 @@ php "$TARGET/composer.phar" config version "$VERSION" -d "$TARGET" php "$TARGET/composer.phar" install --no-dev --prefer-dist -o -d "$TARGET" # Install external modules +php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-adfs php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authfacebook php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authlinkedin php "$TARGET/composer.phar" require --update-no-dev simplesamlphp/simplesamlphp-module-authtwitter diff --git a/composer.json b/composer.json index 2b69f6067..8a42ce37a 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,7 @@ "phpmailer/phpmailer": "^6.0", "robrichards/xmlseclibs": "^3.0", "simplesamlphp/saml2": "^3.3", + "simplesamlphp/simplesamlphp-module-adfs": "^1.0", "simplesamlphp/simplesamlphp-module-authfacebook": "^1.0", "simplesamlphp/simplesamlphp-module-authlinkedin": "^1.0", "simplesamlphp/simplesamlphp-module-authtwitter": "^1.0", diff --git a/modules/adfs/default-disable b/modules/adfs/default-disable deleted file mode 100644 index fa0bd82e2..000000000 --- a/modules/adfs/default-disable +++ /dev/null @@ -1,3 +0,0 @@ -This file indicates that the default state of this module -is disabled. To enable, create a file named enable in the -same directory as this file. diff --git a/modules/adfs/docs/adfs.md b/modules/adfs/docs/adfs.md deleted file mode 100644 index f200fea78..000000000 --- a/modules/adfs/docs/adfs.md +++ /dev/null @@ -1,83 +0,0 @@ -Enables AD FS IdP -Compatible with VS 2012 Identity and Access - -Basic Setup Companion based on: -http://simplesamlphp.org/docs/stable/simplesamlphp-idp - -1. Enabling the Identity Provider functionality - -In config/config.php, the option will be: -'enable.adfs-idp' => true - -2. Authentication module - -Follow as is. - -3. Configuring the authentication module - -In addition to enabling authentication module, enable adfs module by creating a file named 'enable' in modules/adfs - -In unix from installation directory: -touch modules/adfs/enable - -4. Configuring the IdP - -ADFS IdP is configured by metadata stored in /metadata/adfs-idp-hosted.php and metadata/adfs-sp-remote.php - -If they are not present, copy them from /metadata-templates to the metadata -directory. - -5. Using the uri NameFormat on attributes - -WS-FED likes a few parameters to be very specifically named. This is -especially true if .net clients will be treating this as a Microsoft ADFS -IdP. - -The recommended settings for /metadata/adfs-idp-hosted.php is: - -'authproc' => array( - // Convert LDAP names to WS-Fed Claims. - 100 => array('class' => 'core:AttributeMap', 'name2claim'), -), - -6. Adding SPs to the IdP - -The minimal configuration for /metadata/adfs-sp-remote.php is: - -$metadata['urn:federation:localhost'] = array( - 'prp' => 'https://localhost/adfs/ls/', -); - -7. Creating a SSL self signed certificate - -Follow as is. - -8. Adding this IdP to other SPs - -Metadata should be available from /module.php/adfs/idp/metadata.php - -9. This module tries its best to emulate a Microsoft ADFS endpoint, and as -such, it is simplest to test using a .net client. - -To build the test client, follow the tutorial at: -http://code.msdn.microsoft.com/Claims-Aware-Web-d94a89ca - -This will build a .net app that uses a dev machine running STS (their name for -an IdP). - -To point to your SimpleSamlPHP ADFS IdP, in VS 2012: - -a. Right-click the project in Solution Explorer and select the Identity and -Access option. - -b. In the Identity and Access Window, Select Use a business identity -provider. - -c. Under “Enter the path to the STS metadata document” enter the url you have - -from step 8. Something like -https://.../module.php/adfs/idp/metadata.php - -d. Click Ok - -For more information in regards to .NET: http://msdn.microsoft.com/en-us/library/hh377151.aspx diff --git a/modules/adfs/lib/IdP/ADFS.php b/modules/adfs/lib/IdP/ADFS.php deleted file mode 100644 index aecba0b96..000000000 --- a/modules/adfs/lib/IdP/ADFS.php +++ /dev/null @@ -1,396 +0,0 @@ -<?php - -namespace SimpleSAML\Module\adfs\IdP; - -use RobRichards\XMLSecLibs\XMLSecurityDSig; -use RobRichards\XMLSecLibs\XMLSecurityKey; -use SimpleSAML\Utils\Config\Metadata; -use SimpleSAML\Utils\Crypto; - -class ADFS -{ - /** - * @param \SimpleSAML\IdP $idp - * @throws \Exception - * @return void - */ - public static function receiveAuthnRequest(\SimpleSAML\IdP $idp) - { - try { - parse_str($_SERVER['QUERY_STRING'], $query); - - $requestid = $query['wctx']; - $issuer = $query['wtrealm']; - - $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler(); - $spMetadata = $metadata->getMetaDataConfig($issuer, 'adfs-sp-remote'); - - \SimpleSAML\Logger::info('ADFS - IdP.prp: Incoming Authentication request: '.$issuer.' id '.$requestid); - } catch (\Exception $exception) { - throw new \SimpleSAML\Error\Error('PROCESSAUTHNREQUEST', $exception); - } - - $state = [ - 'Responder' => ['\SimpleSAML\Module\adfs\IdP\ADFS', 'sendResponse'], - 'SPMetadata' => $spMetadata->toArray(), - 'ForceAuthn' => false, - 'isPassive' => false, - 'adfs:wctx' => $requestid, - 'adfs:wreply' => false - ]; - - if (isset($query['wreply']) && !empty($query['wreply'])) { - $state['adfs:wreply'] = \SimpleSAML\Utils\HTTP::checkURLAllowed($query['wreply']); - } - - $idp->handleAuthenticationRequest($state); - } - - - /** - * @param string $issuer - * @param string $target - * @param string $nameid - * @param array $attributes - * @param int $assertionLifetime - * @return string - */ - private static function generateResponse($issuer, $target, $nameid, $attributes, $assertionLifetime) - { - $issueInstant = \SimpleSAML\Utils\Time::generateTimestamp(); - $notBefore = \SimpleSAML\Utils\Time::generateTimestamp(time() - 30); - $assertionExpire = \SimpleSAML\Utils\Time::generateTimestamp(time() + $assertionLifetime); - $assertionID = \SimpleSAML\Utils\Random::generateID(); - $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN'; - $nameid = htmlspecialchars($nameid); - $parsed_attrs = []; - - foreach ($attributes as $name => $values) { - if ((!is_array($values)) || (count($values) == 0)) { - continue; - } - - list($namespace, $name) = \SimpleSAML\Utils\Attributes::getAttributeNamespace( - $name, - 'http://schemas.xmlsoap.org/claims' - ); - foreach ($values as $value) { - if ((!isset($value)) || ($value === '')) { - continue; - } - $parsed_attrs[] = ['name' => $name, 'namespace' => $namespace, 'value' => htmlspecialchars($value)]; - } - } - - $config = \SimpleSAML\Configuration::getInstance(); - $t = new \SimpleSAML\XHTML\Template($config, 'adfs:generateResponse.twig'); - $twig = $t->getTwig(); - return $twig->render( - 'adfs:generateResponse.twig', - [ - 'issueInstant' => $issueInstant, - 'notBefore' => $notBefore, - 'issuer' => $issuer, - 'nameid' => $nameid, - 'nameidFormat' => $nameidFormat, - 'target' => $target, - 'assertionID' => $assertionID, - 'assertionExpire' => $assertionExpire, - 'parsedAttributes' => $parsed_attrs, - ] - ); - } - - - /** - * @param string $response - * @param string $key - * @param string $cert - * @param string $algo - * @return string|bool - */ - private static function signResponse($response, $key, $cert, $algo) - { - $objXMLSecDSig = new XMLSecurityDSig(); - $objXMLSecDSig->idKeys = ['AssertionID']; - $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); - $responsedom = \SAML2\DOMDocumentFactory::fromString(str_replace("\r", "", $response)); - $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); - $objXMLSecDSig->addReferenceList( - [$firstassertionroot], - XMLSecurityDSig::SHA256, - ['http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N], - ['id_name' => 'AssertionID'] - ); - - $objKey = new XMLSecurityKey($algo, ['type' => 'private']); - $objKey->loadKey($key, true); - $objXMLSecDSig->sign($objKey); - if ($cert) { - $public_cert = file_get_contents($cert); - $objXMLSecDSig->add509Cert($public_cert, true); - } - $newSig = $responsedom->importNode($objXMLSecDSig->sigNode, true); - $firstassertionroot->appendChild($newSig); - return $responsedom->saveXML(); - } - - - /** - * @param string $url - * @param string $wresult - * @param string $wctx - * @return void - */ - private static function postResponse($url, $wresult, $wctx) - { - $config = \SimpleSAML\Configuration::getInstance(); - $t = new \SimpleSAML\XHTML\Template($config, 'adfs:postResponse.twig'); - $t->data['baseurlpath'] = \SimpleSAML\Module::getModuleURL('adfs'); - $t->data['url'] = $url; - $t->data['wresult'] = $wresult; - $t->data['wctx'] = $wctx; - $t->show(); - } - - - /** - * Get the metadata of a given hosted ADFS IdP. - * - * @param string $entityid The entity ID of the hosted ADFS IdP whose metadata we want to fetch. - * @return array - * - * @throws \SimpleSAML\Error\Exception - * @throws \SimpleSAML\Error\MetadataNotFound - */ - public static function getHostedMetadata($entityid) - { - $handler = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler(); - $config = $handler->getMetaDataConfig($entityid, 'adfs-idp-hosted'); - - $endpoint = \SimpleSAML\Module::getModuleURL('adfs/idp/prp.php'); - $metadata = [ - 'metadata-set' => 'adfs-idp-hosted', - 'entityid' => $entityid, - 'SingleSignOnService' => [ - [ - 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT, - 'Location' => $endpoint, - ] - ], - 'SingleLogoutService' => [ - 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT, - 'Location' => $endpoint, - ], - 'NameIDFormat' => $config->getString('NameIDFormat', \SAML2\Constants::NAMEID_TRANSIENT), - 'contacts' => [], - ]; - - // add certificates - $keys = []; - $certInfo = Crypto::loadPublicKey($config, false, 'new_'); - $hasNewCert = false; - if ($certInfo !== null) { - $keys[] = [ - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => true, - 'X509Certificate' => $certInfo['certData'], - 'prefix' => 'new_', - ]; - $hasNewCert = true; - } - - $certInfo = Crypto::loadPublicKey($config, true); - $keys[] = [ - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => $hasNewCert === false, - 'X509Certificate' => $certInfo['certData'], - 'prefix' => '', - ]; - - if ($config->hasValue('https.certificate')) { - $httpsCert = Crypto::loadPublicKey($config, true, 'https.'); - $keys[] = [ - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => false, - 'X509Certificate' => $httpsCert['certData'], - 'prefix' => 'https.' - ]; - } - $metadata['keys'] = $keys; - - // add organization information - if ($config->hasValue('OrganizationName')) { - $metadata['OrganizationName'] = $config->getLocalizedString('OrganizationName'); - $metadata['OrganizationDisplayName'] = $config->getLocalizedString( - 'OrganizationDisplayName', - $metadata['OrganizationName'] - ); - - if (!$config->hasValue('OrganizationURL')) { - throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.'); - } - $metadata['OrganizationURL'] = $config->getLocalizedString('OrganizationURL'); - } - - // add scope - if ($config->hasValue('scope')) { - $metadata['scope'] = $config->getArray('scope'); - } - - // add extensions - if ($config->hasValue('EntityAttributes')) { - $metadata['EntityAttributes'] = $config->getArray('EntityAttributes'); - - // check for entity categories - if (Metadata::isHiddenFromDiscovery($metadata)) { - $metadata['hide.from.discovery'] = true; - } - } - - if ($config->hasValue('UIInfo')) { - $metadata['UIInfo'] = $config->getArray('UIInfo'); - } - - if ($config->hasValue('DiscoHints')) { - $metadata['DiscoHints'] = $config->getArray('DiscoHints'); - } - - if ($config->hasValue('RegistrationInfo')) { - $metadata['RegistrationInfo'] = $config->getArray('RegistrationInfo'); - } - - // add contact information - $globalConfig = \SimpleSAML\Configuration::getInstance(); - $email = $globalConfig->getString('technicalcontact_email', false); - if ($email && $email !== 'na@example.org') { - $contact = [ - 'emailAddress' => $email, - 'name' => $globalConfig->getString('technicalcontact_name', null), - 'contactType' => 'technical', - ]; - $metadata['contacts'][] = Metadata::getContact($contact); - } - - return $metadata; - } - - - /** - * @param array $state - * @return void - * - * @throws \Exception - */ - public static function sendResponse(array $state) - { - $spMetadata = $state["SPMetadata"]; - $spEntityId = $spMetadata['entityid']; - $spMetadata = \SimpleSAML\Configuration::loadFromArray( - $spMetadata, - '$metadata['.var_export($spEntityId, true).']' - ); - - $attributes = $state['Attributes']; - - $nameidattribute = $spMetadata->getValue('simplesaml.nameidattribute'); - if (!empty($nameidattribute)) { - if (!array_key_exists($nameidattribute, $attributes)) { - throw new \Exception('simplesaml.nameidattribute does not exist in resulting attribute set'); - } - $nameid = $attributes[$nameidattribute][0]; - } else { - $nameid = \SimpleSAML\Utils\Random::generateID(); - } - - $idp = \SimpleSAML\IdP::getByState($state); - $idpMetadata = $idp->getConfig(); - $idpEntityId = $idpMetadata->getString('entityid'); - - $idp->addAssociation([ - 'id' => 'adfs:'.$spEntityId, - 'Handler' => '\SimpleSAML\Module\adfs\IdP\ADFS', - 'adfs:entityID' => $spEntityId, - ]); - - $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', null); - if ($assertionLifetime === null) { - $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300); - } - - $response = ADFS::generateResponse($idpEntityId, $spEntityId, $nameid, $attributes, $assertionLifetime); - - $privateKeyFile = \SimpleSAML\Utils\Config::getCertPath($idpMetadata->getString('privatekey')); - $certificateFile = \SimpleSAML\Utils\Config::getCertPath($idpMetadata->getString('certificate')); - - $algo = $spMetadata->getString('signature.algorithm', null); - if ($algo === null) { - $algo = $idpMetadata->getString('signature.algorithm', XMLSecurityKey::RSA_SHA256); - } - $wresult = ADFS::signResponse($response, $privateKeyFile, $certificateFile, $algo); - - $wctx = $state['adfs:wctx']; - $wreply = $state['adfs:wreply'] ? : $spMetadata->getValue('prp'); - ADFS::postResponse($wreply, $wresult, $wctx); - } - - - /** - * @param \SimpleSAML\IdP $idp - * @param array $state - * @return void - */ - public static function sendLogoutResponse(\SimpleSAML\IdP $idp, array $state) - { - // NB:: we don't know from which SP the logout request came from - $idpMetadata = $idp->getConfig(); - \SimpleSAML\Utils\HTTP::redirectTrustedURL( - $idpMetadata->getValue('redirect-after-logout', \SimpleSAML\Utils\HTTP::getBaseURL()) - ); - } - - - /** - * @param \SimpleSAML\IdP $idp - * @return void - */ - public static function receiveLogoutMessage(\SimpleSAML\IdP $idp) - { - // if a redirect is to occur based on wreply, we will redirect to url as - // this implies an override to normal sp notification - if (isset($_GET['wreply']) && !empty($_GET['wreply'])) { - $idp->doLogoutRedirect(\SimpleSAML\Utils\HTTP::checkURLAllowed($_GET['wreply'])); - assert(false); - } - - $state = [ - 'Responder' => ['\SimpleSAML\Module\adfs\IdP\ADFS', 'sendLogoutResponse'], - ]; - $assocId = null; - // TODO: verify that this is really no problem for: - // a) SSP, because there's no caller SP. - // b) ADFS SP because caller will be called back.. - $idp->handleLogoutRequest($state, $assocId); - } - - - /** - * Accepts an association array, and returns a URL that can be accessed to terminate the association - * @param \SimpleSAML\IdP $idp - * @param array $association - * @param string $relayState - * @return string - */ - public static function getLogoutURL(\SimpleSAML\IdP $idp, array $association, $relayState) - { - $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler(); - $spMetadata = $metadata->getMetaDataConfig($association['adfs:entityID'], 'adfs-sp-remote'); - $returnTo = \SimpleSAML\Module::getModuleURL( - 'adfs/idp/prp.php?assocId='.urlencode($association["id"]).'&relayState='.urlencode($relayState) - ); - return $spMetadata->getValue('prp').'?wa=wsignoutcleanup1.0&wreply='.urlencode($returnTo); - } -} diff --git a/modules/adfs/lib/SAML2/XML/fed/Constants.php b/modules/adfs/lib/SAML2/XML/fed/Constants.php deleted file mode 100644 index db326b348..000000000 --- a/modules/adfs/lib/SAML2/XML/fed/Constants.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php - -namespace SimpleSAML\Module\adfs\SAML2\XML\fed; - -/** - * Class holding constants relevant for ADFS. - * - * @package SimpleSAMLphp - */ - -class Constants -{ - /** - * The namespace for WS-FED protocol. - */ - const NS_FED = 'http://docs.oasis-open.org/wsfed/federation/200706'; -} diff --git a/modules/adfs/lib/SAML2/XML/fed/Endpoint.php b/modules/adfs/lib/SAML2/XML/fed/Endpoint.php deleted file mode 100644 index 46b494025..000000000 --- a/modules/adfs/lib/SAML2/XML/fed/Endpoint.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php - -namespace SimpleSAML\Module\adfs\SAML2\XML\fed; - -/** - * Class representing fed Endpoint. - * - * @package SimpleSAMLphp - */ - -class Endpoint -{ - /** - * Add this endpoint to an XML element. - * - * @param \DOMElement $parent The element we should append this endpoint to. - * @param string $name The name of the element we should create. - * @param string $address - * @return \DOMElement - */ - public static function appendXML(\DOMElement $parent, $name, $address) - { - assert(is_string($name)); - assert(is_string($address)); - - $e = $parent->ownerDocument->createElement($name); - $parent->appendChild($e); - - $endpoint = $parent->ownerDocument->createElement('EndpointReference'); - $endpoint->setAttribute('xmlns', 'http://www.w3.org/2005/08/addressing'); - $e->appendChild($endpoint); - - $address = $parent->ownerDocument->createElement('Address', $address); - $endpoint->appendChild($address); - - return $e; - } -} diff --git a/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php b/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php deleted file mode 100644 index e3fc90e01..000000000 --- a/modules/adfs/lib/SAML2/XML/fed/SecurityTokenServiceType.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php - -namespace SimpleSAML\Module\adfs\SAML2\XML\fed; - -/** - * Class representing SecurityTokenServiceType RoleDescriptor. - * - * @package SimpleSAMLphp - */ - -class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor -{ - /** - * List of supported protocols. - * - * @var array - */ - public $protocolSupportEnumeration = [Constants::NS_FED]; - - /** - * The Location of Services. - * - * @var string|null - */ - public $Location = null; - - - /** - * Initialize a SecurityTokenServiceType element. - * - * @param \DOMElement|null $xml The XML element we should load. - */ - public function __construct(\DOMElement $xml = null) - { - parent::__construct('RoleDescriptor', $xml); - if ($xml === null) { - return; - } - } - - - /** - * Convert this SecurityTokenServiceType RoleDescriptor to XML. - * - * @param \DOMElement $parent The element we should add this contact to. - * @return \DOMElement The new ContactPerson-element. - */ - public function toXML(\DOMElement $parent) - { - assert(is_string($this->Location)); - - $e = parent::toXML($parent); - $e->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:fed', Constants::NS_FED); - $e->setAttributeNS(\SAML2\Constants::NS_XSI, 'xsi:type', 'fed:SecurityTokenServiceType'); - TokenTypesOffered::appendXML($e); - Endpoint::appendXML($e, 'SecurityTokenServiceEndpoint', $this->Location); - Endpoint::appendXML($e, 'fed:PassiveRequestorEndpoint', $this->Location); - - return $e; - } - - - /** - * Get the location of this service. - * - * @return string|null The full URL where this service can be reached. - */ - public function getLocation() - { - return $this->Location; - } - - - /** - * Set the location of this service. - * - * @param string $location The full URL where this service can be reached. - * @return void - */ - public function setLocation($location) - { - $this->Location = $location; - } -} diff --git a/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php b/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php deleted file mode 100644 index 659628ada..000000000 --- a/modules/adfs/lib/SAML2/XML/fed/TokenTypesOffered.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -namespace SimpleSAML\Module\adfs\SAML2\XML\fed; - -/** - * Class representing fed TokenTypesOffered. - * - * @package SimpleSAMLphp - */ - -class TokenTypesOffered -{ - /** - * Add tokentypesoffered to an XML element. - * - * @param \DOMElement $parent The element we should append this endpoint to. - * @return \DOMElement - */ - public static function appendXML(\DOMElement $parent) - { - $e = $parent->ownerDocument->createElementNS(Constants::NS_FED, 'fed:TokenTypesOffered'); - $parent->appendChild($e); - - $tokentype = $parent->ownerDocument->createElementNS(Constants::NS_FED, 'fed:TokenType'); - $tokentype->setAttribute('Uri', 'urn:oasis:names:tc:SAML:1.0:assertion'); - $e->appendChild($tokentype); - - return $e; - } -} diff --git a/modules/adfs/templates/generateResponse.twig b/modules/adfs/templates/generateResponse.twig deleted file mode 100644 index 2d5f9a476..000000000 --- a/modules/adfs/templates/generateResponse.twig +++ /dev/null @@ -1,31 +0,0 @@ -<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 }}">{{ nameid }}</saml:NameIdentifier> - </saml:Subject> - </saml:AuthenticationStatement> - <saml:AttributeStatement> - <saml:Subject> - <saml:NameIdentifier Format="{{ nameidFormat }}">{{ nameid }}</saml:NameIdentifier> - </saml:Subject> -{% for attr in parsedAttributes %} - <saml:Attribute AttributeNamespace="{{ attr.namespace }}" AttributeName="{{ attr.name }}"> - <saml:AttributeValue>{{ attr.value }}</saml:AttributeValue> - </saml:Attribute> -{% endfor %} - </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> diff --git a/modules/adfs/templates/postResponse.twig b/modules/adfs/templates/postResponse.twig deleted file mode 100644 index 16f0eab18..000000000 --- a/modules/adfs/templates/postResponse.twig +++ /dev/null @@ -1,16 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <script src="/{{ baseurlpath }}module.php/adfs/assets/js/postResponse.js"></script> - </head> - <body> - <form method="post" action="{{ url }}"> - <input type="hidden" name="wa" value="wsignin1.0"> - <input type="hidden" name="wresult" value="{{ wresult|escape('html') }}"> - <input type="hidden" name="wctx" value="{{ wctx|escape('html') }}"> - <noscript> - <input type="submit" value="Continue"> - </noscript> - </form> - </body> -</html> diff --git a/modules/adfs/www/assets/js/postResponse.js b/modules/adfs/www/assets/js/postResponse.js deleted file mode 100644 index a813b92cb..000000000 --- a/modules/adfs/www/assets/js/postResponse.js +++ /dev/null @@ -1,3 +0,0 @@ -document.addEventListener('DOMContentLoaded', function () { - document.forms[0].submit(); -}); diff --git a/modules/adfs/www/idp/metadata.php b/modules/adfs/www/idp/metadata.php deleted file mode 100644 index 0f7dce545..000000000 --- a/modules/adfs/www/idp/metadata.php +++ /dev/null @@ -1,183 +0,0 @@ -<?php - -// load configuration and metadata -$config = \SimpleSAML\Configuration::getInstance(); -$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler(); - -if (!$config->getBoolean('enable.adfs-idp', false)) { - throw new \SimpleSAML\Error\Error('NOACCESS'); -} - -// check if valid local session exists -if ($config->getBoolean('admin.protectmetadata', false)) { - \SimpleSAML\Utils\Auth::requireAdmin(); -} - -try { - $idpentityid = isset($_GET['idpentityid']) ? - $_GET['idpentityid'] : $metadata->getMetaDataCurrentEntityID('adfs-idp-hosted'); - $idpmeta = $metadata->getMetaDataConfig($idpentityid, 'adfs-idp-hosted'); - - $availableCerts = []; - - $keys = []; - $certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, false, 'new_'); - if ($certInfo !== null) { - $availableCerts['new_idp.crt'] = $certInfo; - $keys[] = [ - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => true, - 'X509Certificate' => $certInfo['certData'], - ]; - $hasNewCert = true; - } else { - $hasNewCert = false; - } - - $certInfo = \SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true); - $availableCerts['idp.crt'] = $certInfo; - $keys[] = [ - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => ($hasNewCert ? false : true), - 'X509Certificate' => $certInfo['certData'], - ]; - - if ($idpmeta->hasValue('https.certificate')) { - $httpsCert = \SimpleSAML\Utils\Crypto::loadPublicKey($idpmeta, true, 'https.'); - assert(isset($httpsCert['certData'])); - $availableCerts['https.crt'] = $httpsCert; - $keys[] = [ - 'type' => 'X509Certificate', - 'signing' => true, - 'encryption' => false, - 'X509Certificate' => $httpsCert['certData'], - ]; - } - - $adfs_service_location = \SimpleSAML\Module::getModuleURL('adfs').'/idp/prp.php'; - $metaArray = [ - 'metadata-set' => 'adfs-idp-remote', - 'entityid' => $idpentityid, - 'SingleSignOnService' => [ - 0 => [ - 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT, - 'Location' => $adfs_service_location - ] - ], - 'SingleLogoutService' => [ - 0 => [ - 'Binding' => \SAML2\Constants::BINDING_HTTP_REDIRECT, - 'Location' => $adfs_service_location - ] - ], - ]; - - if (count($keys) === 1) { - $metaArray['certData'] = $keys[0]['X509Certificate']; - } else { - $metaArray['keys'] = $keys; - } - - $metaArray['NameIDFormat'] = $idpmeta->getString( - 'NameIDFormat', - 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' - ); - - if ($idpmeta->hasValue('OrganizationName')) { - $metaArray['OrganizationName'] = $idpmeta->getLocalizedString('OrganizationName'); - $metaArray['OrganizationDisplayName'] = $idpmeta->getLocalizedString( - 'OrganizationDisplayName', - $metaArray['OrganizationName'] - ); - - if (!$idpmeta->hasValue('OrganizationURL')) { - throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.'); - } - $metaArray['OrganizationURL'] = $idpmeta->getLocalizedString('OrganizationURL'); - } - - if ($idpmeta->hasValue('scope')) { - $metaArray['scope'] = $idpmeta->getArray('scope'); - } - - if ($idpmeta->hasValue('EntityAttributes')) { - $metaArray['EntityAttributes'] = $idpmeta->getArray('EntityAttributes'); - } - - if ($idpmeta->hasValue('UIInfo')) { - $metaArray['UIInfo'] = $idpmeta->getArray('UIInfo'); - } - - if ($idpmeta->hasValue('DiscoHints')) { - $metaArray['DiscoHints'] = $idpmeta->getArray('DiscoHints'); - } - - if ($idpmeta->hasValue('RegistrationInfo')) { - $metaArray['RegistrationInfo'] = $idpmeta->getArray('RegistrationInfo'); - } - - $metaflat = '$metadata['.var_export($idpentityid, true).'] = '.var_export($metaArray, true).';'; - - $metaBuilder = new \SimpleSAML\Metadata\SAMLBuilder($idpentityid); - $metaBuilder->addSecurityTokenServiceType($metaArray); - $metaBuilder->addOrganizationInfo($metaArray); - $technicalContactEmail = $config->getString('technicalcontact_email', null); - if ($technicalContactEmail && $technicalContactEmail !== 'na@example.org') { - $metaBuilder->addContact('technical', \SimpleSAML\Utils\Config\Metadata::getContact([ - 'emailAddress' => $technicalContactEmail, - 'name' => $config->getString('technicalcontact_name', null), - 'contactType' => 'technical', - ])); - } - $output_xhtml = array_key_exists('output', $_GET) && $_GET['output'] == 'xhtml'; - $metaxml = $metaBuilder->getEntityDescriptorText($output_xhtml); - if (!$output_xhtml) { - $metaxml = str_replace("\n", '', $metaxml); - } - - // sign the metadata if enabled - $metaxml = \SimpleSAML\Metadata\Signer::sign($metaxml, $idpmeta->toArray(), 'ADFS IdP'); - - if ($output_xhtml) { - $defaultidp = $config->getString('default-adfs-idp', null); - - $t = new \SimpleSAML\XHTML\Template($config, 'saml:metadata.php', 'admin'); - - $t->data['clipboard.js'] = true; - $t->data['available_certs'] = $availableCerts; - $certdata = []; - foreach (array_keys($availableCerts) as $availableCert) { - $certdata[$availableCert]['name'] = $availableCert; - $certdata[$availableCert]['url'] = \SimpleSAML\Module::getModuleURL('saml/idp/certs.php'). - '/'.$availableCert; - - $certdata[$availableCert]['comment'] = ''; - if ($availableCerts[$availableCert]['certFingerprint'][0] === 'afe71c28ef740bc87425be13a2263d37971da1f9') { - $certdata[$availableCert]['comment'] = 'This is the default certificate.'. - ' Generate a new certificate if this is a production system.'; - } - } - $t->data['certdata'] = $certdata; - $t->data['header'] = 'adfs-idp'; // TODO: Replace with headerString in 2.0 - $t->data['headerString'] = \SimpleSAML\Locale\Translate::noop('metadata_adfs-idp'); - $t->data['metaurl'] = \SimpleSAML\Utils\HTTP::getSelfURLNoQuery(); - $t->data['metadata'] = htmlspecialchars($metaxml); - $t->data['metadataflat'] = htmlspecialchars($metaflat); - $t->data['defaultidp'] = $defaultidp; - $t->show(); - } else { - header('Content-Type: application/xml'); - - // make sure to export only the md:EntityDescriptor - $metaxml = substr($metaxml, strpos($metaxml, '<md:EntityDescriptor')); - // 22 = strlen('</md:EntityDescriptor>') - $metaxml = substr($metaxml, 0, strrpos($metaxml, '</md:EntityDescriptor>') + 22); - echo $metaxml; - - exit(0); - } -} catch (\Exception $exception) { - throw new \SimpleSAML\Error\Error('METADATA', $exception); -} diff --git a/modules/adfs/www/idp/prp.php b/modules/adfs/www/idp/prp.php deleted file mode 100644 index 03a973b11..000000000 --- a/modules/adfs/www/idp/prp.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -/** - * ADFS PRP IDP protocol support for SimpleSAMLphp. - * - * @author Hans Zandbelt, SURFnet bv, <hans.zandbelt@surfnet.nl> - * @package SimpleSAMLphp - */ - -\SimpleSAML\Logger::info('ADFS - IdP.prp: Accessing ADFS IdP endpoint prp'); - -$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler(); -$idpEntityId = $metadata->getMetaDataCurrentEntityID('adfs-idp-hosted'); -$idp = \SimpleSAML\IdP::getById('adfs:'.$idpEntityId); - -if (isset($_GET['wa'])) { - if ($_GET['wa'] === 'wsignout1.0') { - \SimpleSAML\Module\adfs\IdP\ADFS::receiveLogoutMessage($idp); - } elseif ($_GET['wa'] === 'wsignin1.0') { - \SimpleSAML\Module\adfs\IdP\ADFS::receiveAuthnRequest($idp); - } - assert(false); -} elseif (isset($_GET['assocId'])) { - // logout response from ADFS SP - $assocId = $_GET['assocId']; // Association ID of the SP that sent the logout response - $relayState = $_GET['relayState']; // Data that was sent in the logout request to the SP. Can be null - $logoutError = null; // null on success, or an instance of a \SimpleSAML\Error\Exception on failure. - $idp->handleLogoutResponse($assocId, $relayState, $logoutError); -} -- GitLab