Skip to content
Snippets Groups Projects
Commit 4e29a1a3 authored by Tim van Dijen's avatar Tim van Dijen
Browse files

Fixes for modules/adfs

parent 06375d51
No related branches found
No related tags found
No related merge requests found
...@@ -9,6 +9,11 @@ use SimpleSAML\Utils\Crypto; ...@@ -9,6 +9,11 @@ use SimpleSAML\Utils\Crypto;
class ADFS class ADFS
{ {
/**
* @param \SimpleSAML\IdP $idp
* @throws \Exception
* @return void
*/
public static function receiveAuthnRequest(\SimpleSAML\IdP $idp) public static function receiveAuthnRequest(\SimpleSAML\IdP $idp)
{ {
try { try {
...@@ -41,6 +46,15 @@ class ADFS ...@@ -41,6 +46,15 @@ class ADFS
$idp->handleAuthenticationRequest($state); $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) private static function generateResponse($issuer, $target, $nameid, $attributes, $assertionLifetime)
{ {
$issueInstant = \SimpleSAML\Utils\Time::generateTimestamp(); $issueInstant = \SimpleSAML\Utils\Time::generateTimestamp();
...@@ -49,26 +63,7 @@ class ADFS ...@@ -49,26 +63,7 @@ class ADFS
$assertionID = \SimpleSAML\Utils\Random::generateID(); $assertionID = \SimpleSAML\Utils\Random::generateID();
$nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN'; $nameidFormat = 'http://schemas.xmlsoap.org/claims/UPN';
$nameid = htmlspecialchars($nameid); $nameid = htmlspecialchars($nameid);
$parsed_attrs = [];
$result = <<<MSG
<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>
MSG;
foreach ($attributes as $name => $values) { foreach ($attributes as $name => $values) {
if ((!is_array($values)) || (count($values) == 0)) { if ((!is_array($values)) || (count($values) == 0)) {
...@@ -83,31 +78,37 @@ MSG; ...@@ -83,31 +78,37 @@ MSG;
if ((!isset($value)) || ($value === '')) { if ((!isset($value)) || ($value === '')) {
continue; continue;
} }
$value = htmlspecialchars($value); $parsed_attrs[] = ['name' => $name, 'namespace' => $namespace, 'value' => htmlspecialchars($value)];
$result .= <<<MSG
<saml:Attribute AttributeNamespace="$namespace" AttributeName="$name">
<saml:AttributeValue>$value</saml:AttributeValue>
</saml:Attribute>
MSG;
} }
} }
$result .= <<<MSG $config = \SimpleSAML\Configuration::getInstance();
</saml:AttributeStatement> $t = new \SimpleSAML\XHTML\Template($config, 'adfs:generateResponse.twig');
</saml:Assertion> $twig = $t->getTwig();
</wst:RequestedSecurityToken> return $twig->render(
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> 'adfs:generateResponse.twig',
<wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> [
<wsa:Address>$target</wsa:Address> 'issueInstant' => $issueInstant,
</wsa:EndpointReference> 'notBefore' => $notBefore,
</wsp:AppliesTo> 'issuer' => $issuer,
</wst:RequestSecurityTokenResponse> 'nameid' => $nameid,
MSG; 'nameidFormat' => $nameidFormat,
'target' => $target,
return $result; '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) private static function signResponse($response, $key, $cert, $algo)
{ {
$objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig = new XMLSecurityDSig();
...@@ -134,6 +135,13 @@ MSG; ...@@ -134,6 +135,13 @@ MSG;
return $responsedom->saveXML(); return $responsedom->saveXML();
} }
/**
* @param string $url
* @param string $wresult
* @param string $wctx
* @return void
*/
private static function postResponse($url, $wresult, $wctx) private static function postResponse($url, $wresult, $wctx)
{ {
$config = \SimpleSAML\Configuration::getInstance(); $config = \SimpleSAML\Configuration::getInstance();
...@@ -150,8 +158,8 @@ MSG; ...@@ -150,8 +158,8 @@ MSG;
* Get the metadata of a given hosted ADFS IdP. * 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. * @param string $entityid The entity ID of the hosted ADFS IdP whose metadata we want to fetch.
*
* @return array * @return array
*
* @throws \SimpleSAML\Error\Exception * @throws \SimpleSAML\Error\Exception
* @throws \SimpleSAML\Error\MetadataNotFound * @throws \SimpleSAML\Error\MetadataNotFound
*/ */
...@@ -223,7 +231,7 @@ MSG; ...@@ -223,7 +231,7 @@ MSG;
); );
if (!$config->hasValue('OrganizationURL')) { if (!$config->hasValue('OrganizationURL')) {
throw new \SimpleSAMl\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.'); throw new \SimpleSAML\Error\Exception('If OrganizationName is set, OrganizationURL must also be set.');
} }
$metadata['OrganizationURL'] = $config->getLocalizedString('OrganizationURL'); $metadata['OrganizationURL'] = $config->getLocalizedString('OrganizationURL');
} }
...@@ -271,6 +279,12 @@ MSG; ...@@ -271,6 +279,12 @@ MSG;
} }
/**
* @param array $state
* @return void
*
* @throws \Exception
*/
public static function sendResponse(array $state) public static function sendResponse(array $state)
{ {
$spMetadata = $state["SPMetadata"]; $spMetadata = $state["SPMetadata"];
...@@ -323,6 +337,12 @@ MSG; ...@@ -323,6 +337,12 @@ MSG;
ADFS::postResponse($wreply, $wresult, $wctx); ADFS::postResponse($wreply, $wresult, $wctx);
} }
/**
* @param \SimpleSAML\IdP $idp
* @param array $state
* @return void
*/
public static function sendLogoutResponse(\SimpleSAML\IdP $idp, array $state) public static function sendLogoutResponse(\SimpleSAML\IdP $idp, array $state)
{ {
// NB:: we don't know from which SP the logout request came from // NB:: we don't know from which SP the logout request came from
...@@ -332,6 +352,11 @@ MSG; ...@@ -332,6 +352,11 @@ MSG;
); );
} }
/**
* @param \SimpleSAML\IdP $idp
* @return void
*/
public static function receiveLogoutMessage(\SimpleSAML\IdP $idp) public static function receiveLogoutMessage(\SimpleSAML\IdP $idp)
{ {
// if a redirect is to occur based on wreply, we will redirect to url as // if a redirect is to occur based on wreply, we will redirect to url as
...@@ -351,7 +376,14 @@ MSG; ...@@ -351,7 +376,14 @@ MSG;
$idp->handleLogoutRequest($state, $assocId); $idp->handleLogoutRequest($state, $assocId);
} }
// accepts an association array, and returns a URL that can be accessed to terminate the association
/**
* 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) public static function getLogoutURL(\SimpleSAML\IdP $idp, array $association, $relayState)
{ {
$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler(); $metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();
......
...@@ -15,6 +15,8 @@ class Endpoint ...@@ -15,6 +15,8 @@ class Endpoint
* *
* @param \DOMElement $parent The element we should append this endpoint to. * @param \DOMElement $parent The element we should append this endpoint to.
* @param string $name The name of the element we should create. * @param string $name The name of the element we should create.
* @param string $address
* @return \DOMElement
*/ */
public static function appendXML(\DOMElement $parent, $name, $address) public static function appendXML(\DOMElement $parent, $name, $address)
{ {
......
...@@ -20,9 +20,10 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor ...@@ -20,9 +20,10 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor
/** /**
* The Location of Services. * The Location of Services.
* *
* @var string * @var string|null
*/ */
public $Location; public $Location = null;
/** /**
* Initialize a SecurityTokenServiceType element. * Initialize a SecurityTokenServiceType element.
...@@ -37,6 +38,7 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor ...@@ -37,6 +38,7 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor
} }
} }
/** /**
* Convert this SecurityTokenServiceType RoleDescriptor to XML. * Convert this SecurityTokenServiceType RoleDescriptor to XML.
* *
...@@ -61,7 +63,7 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor ...@@ -61,7 +63,7 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor
/** /**
* Get the location of this service. * Get the location of this service.
* *
* @return string The full URL where this service can be reached. * @return string|null The full URL where this service can be reached.
*/ */
public function getLocation() public function getLocation()
{ {
...@@ -73,6 +75,7 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor ...@@ -73,6 +75,7 @@ class SecurityTokenServiceType extends \SAML2\XML\md\RoleDescriptor
* Set the location of this service. * Set the location of this service.
* *
* @param string $location The full URL where this service can be reached. * @param string $location The full URL where this service can be reached.
* @return void
*/ */
public function setLocation($location) public function setLocation($location)
{ {
......
...@@ -14,6 +14,7 @@ class TokenTypesOffered ...@@ -14,6 +14,7 @@ class TokenTypesOffered
* Add tokentypesoffered to an XML element. * Add tokentypesoffered to an XML element.
* *
* @param \DOMElement $parent The element we should append this endpoint to. * @param \DOMElement $parent The element we should append this endpoint to.
* @return \DOMElement
*/ */
public static function appendXML(\DOMElement $parent) public static function appendXML(\DOMElement $parent)
{ {
......
<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>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment