Skip to content

Commit

Permalink
Add usernamemixed endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdijen committed Oct 22, 2024
1 parent f6a90b6 commit 1fdcb9a
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 13 deletions.
13 changes: 5 additions & 8 deletions src/Controller/Adfs.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@
use SimpleSAML\Module\adfs\IdP\MetadataBuilder;
use SimpleSAML\Module\adfs\MetadataExchange;
use SimpleSAML\SOAP\XML\env_200305\Envelope;
use SimpleSAML\WSSecurity\XML\wsa_200508\{Action, EndpointReference, MessageID, To};
use SimpleSAML\WSSecurity\XML\wsp\AppliesTo;
use SimpleSAML\WSSecurity\XML\wsse\Security;
use SimpleSAML\WSSecurity\XML\wst_200502\RequestSecurityToken;
use SimpleSAML\XML\DOMDocumentFactory;
use Symfony\Component\HttpFoundation\{Request, Response, StreamedResponse};

Expand Down Expand Up @@ -232,6 +228,7 @@ public function usernamemixed(Request $request): Response
$domDocument = DOMDocumentFactory::fromString($soapMessage);
$soapEnvelope = Envelope::fromXML($domDocument->documentElement);

/*
$header = $soapEnvelope->getHeader();
$body = $soapEnvelope->getBody();
Expand Down Expand Up @@ -268,17 +265,17 @@ public function usernamemixed(Request $request): Response
$endpointReference = $elt;
}
}
*/

// Make sure the message was addressed to us.
if ($to === null || $request->server->get('SCRIPT_URI') !== $to->getContent()) {
throw new SspError\BadRequest('This server is not the audience for the message received.');
}

// Ensure we know the issuer (handled by the MetaDataStorageHandler
// Ensure we know the issuer
$issuer = $endpointReference->getAddress()->getContent();
$metadata = MetaDataStorageHandler::getMetadataHandler(Configuration::getInstance());
$spMetadata = $metadata->getMetaDataConfig($issuer, 'adfs-sp-remote');
$idp = IdP::getById($this->config, 'adfs:' . $issuer);

\SimpleSAML\Logger::debug(var_export($endpointReference->getAddress()->getContent(), true));
return ADFS_IDP::receivePassiveAuthnRequest($request, $soapEnvelope, $idp);
}
}
109 changes: 104 additions & 5 deletions src/IdP/ADFS.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use SimpleSAML\Logger;
use SimpleSAML\Metadata\MetaDataStorageHandler;
use SimpleSAML\Module;
use SimpleSAML\SAML11\Constants as C;
use SimpleSAML\SAML11\XML\saml\Assertion;
use SimpleSAML\SAML11\XML\saml\Attribute;
use SimpleSAML\SAML11\XML\saml\AttributeStatement;
Expand All @@ -25,12 +24,13 @@
use SimpleSAML\SAML11\XML\saml\Conditions;
use SimpleSAML\SAML11\XML\saml\NameIdentifier;
use SimpleSAML\SAML11\XML\saml\Subject;
use SimpleSAML\SAML2\Constants as C;
use SimpleSAML\SOAP\XML\env_200305\Envelope;
use SimpleSAML\Utils;
use SimpleSAML\WSSecurity\XML\wsa_200508\Address;
use SimpleSAML\WSSecurity\XML\wsa_200508\EndpointReference;
use SimpleSAML\WSSecurity\XML\wsa_200508\{Action, Address, EndpointReference, MessageID, To};
use SimpleSAML\WSSecurity\XML\wsp\AppliesTo;
use SimpleSAML\WSSecurity\XML\wst_200502\RequestSecurityToken;
use SimpleSAML\WSSecurity\XML\wst_200502\RequestSecurityTokenResponse;
use SimpleSAML\WSSecurity\XML\wsse\{Password, Security, Username};
use SimpleSAML\WSSecurity\XML\wst_200502\{RequestSecurityToken, RequestSecurityTokenResponse};
use SimpleSAML\XHTML\Template;
use SimpleSAML\XMLSecurity\Alg\Signature\SignatureAlgorithmFactory;
use SimpleSAML\XMLSecurity\Key\PrivateKey;
Expand All @@ -41,13 +41,102 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;

use function array_pop;
use function base64_encode;
use function chunk_split;
use function trim;

class ADFS
{
/**
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \SimpleSAML\SOAP\XML\env_200305\Envelope $soapEnvelope
* @param \SimpleSAML\IdP $idp
* @throws \SimpleSAML\Error\MetadataNotFound
*/
public static function receivePassiveAuthnRequest(
Request $request,
Envelope $soapEnvelope,
IdP $idp,
): StreamedResponse {
$header = $soapEnvelope->getHeader();
$body = $soapEnvelope->getBody();

$to = $action = $messageid = $security = null;
foreach ($header->getElements() as $elt) {
if ($elt instanceof To) {
$to = $elt;
} elseif ($elt instanceof Action) {
$action = $elt;
} elseif ($elt instanceof MessageID) {
$messageid = $elt;
} elseif ($elt instanceof Security) {
$security = $elt;
}
}

$requestSecurityToken = null;
foreach ($body->getElements() as $elt) {
if ($elt instanceof RequestSecurityToken) {
$requestSecurityToken = $elt;
}
}

$appliesTo = null;
foreach ($requestSecurityToken->getElements() as $elt) {
if ($elt instanceof AppliesTo) {
$appliesTo = $elt;
}
}

$endpointReference = null;
foreach ($appliesTo->getElements() as $elt) {
if ($elt instanceof EndpointReference) {
$endpointReference = $elt;
}
}

// Make sure the message was addressed to us.
if ($to === null || $request->server->get('SCRIPT_URI') !== $to->getContent()) {
throw new Error\BadRequest('This server is not the audience for the message received.');
}

// Ensure we know the issuer
$issuer = $endpointReference->getAddress()->getContent();
$idp = IdP::getById($this->config, 'adfs:' . $issuer);

$metadata = MetaDataStorageHandler::getMetadataHandler(Configuration::getInstance());
$spMetadata = $metadata->getMetaDataConfig($issuer, 'adfs-sp-remote');

$username = Username::getChildrenOfClass($security->toXML());
$password = Password::getChildrenOfClass($security->toXML());
$username = array_pop($username);
$password = array_pop($password);

if ($username === null || $password === null) {
throw new Error\BadRequest('Missing username or password in SOAP header.');
} else {
$_SERVER['PHP_AUTH_USER'] = $username->getContent();
$_SERVER['PHP_AUTH_PW'] = $password->getContent();
}

$state = [
'Responder' => [ADFS::class, 'sendPassiveResponse'],
'SPMetadata' => $spMetadata->toArray(),
// Dirty hack to leverage the SAML ECP logics
'saml:Binding' => C::BINDING_PAOS,
];

return new StreamedResponse(
function () use ($idp, &$state) {
$idp->handleAuthenticationRequest($state);
},
);
}


/**
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \SimpleSAML\IdP $idp
* @throws \SimpleSAML\Error\MetadataNotFound
*/
Expand Down Expand Up @@ -396,6 +485,16 @@ public static function getHostedMetadata(string $entityid, MetaDataStorageHandle
}


/**
* @param array $state
* @throws \Exception
*/
public static function sendPassiveResponse(array $state): void
{
\SimpleSAML\Logger::debug(var_export($state, true));
}


/**
* @param array $state
* @throws \Exception
Expand Down

0 comments on commit 1fdcb9a

Please sign in to comment.