56 assert(
'is_bool($messageValidated)');
64 assert(
'is_string($xml)');
69 throw new \Exception(
'Unable to parse AuthnResponse XML.');
85 assert(
'$this->dom instanceof DOMDocument');
87 if ($this->messageValidated) {
93 $this->validator =
new Validator($this->dom,
array(
'ResponseID',
'AssertionID'));
102 $publicKeys = $md->getPublicKeys(
'signing');
103 if ($publicKeys !== null) {
104 $certFingerprints =
array();
105 foreach ($publicKeys as
$key) {
106 if ($key[
'type'] !==
'X509Certificate') {
109 $certFingerprints[] = sha1(base64_decode($key[
'X509Certificate']));
111 $this->validator->validateFingerprint($certFingerprints);
112 } elseif ($md->hasValue(
'certFingerprint')) {
113 $certFingerprints = $md->getArrayizeString(
'certFingerprint');
116 $this->validator->validateFingerprint($certFingerprints);
117 } elseif ($md->hasValue(
'caFile')) {
121 throw new \SimpleSAML_Error_Exception(
'Missing certificate in Shibboleth 1.3 IdP Remote metadata for identity provider [' .
$issuer .
'].');
136 if ($this->messageValidated) {
141 if ($this->validator === null) {
147 $node = dom_import_simplexml($node);
150 assert(
'$node instanceof DOMNode');
152 return $this->validator->isNodeValidated($node);
166 assert(
'is_string($query)');
167 assert(
'$this->dom instanceof DOMDocument');
169 if ($node === null) {
170 $node = $this->dom->documentElement;
173 assert(
'$node instanceof DOMNode');
175 $xPath = new \DOMXpath($this->dom);
176 $xPath->registerNamespace(
'shibp', self::SHIB_PROTOCOL_NS);
177 $xPath->registerNamespace(
'shib', self::SHIB_ASSERT_NS);
179 return $xPath->query(
$query, $node);
189 assert(
'$this->dom instanceof DOMDocument');
191 $query =
'/shibp:Response/shib:Assertion/shib:AuthnStatement';
193 if ($node = $nodelist->item(0)) {
194 return $node->getAttribute(
'SessionIndex');
201 public function getAttributes()
205 $base64 = isset($md[
'base64attributes']) ? $md[
'base64attributes'] :
false;
213 $assertions = $this->
doXPathQuery(
'/shibp:Response/shib:Assertion');
215 foreach ($assertions as $assertion) {
217 throw new \Exception(
'Shib13 AuthnResponse contained an unsigned assertion.');
220 $conditions = $this->
doXPathQuery(
'shib:Conditions', $assertion);
221 if ($conditions && $conditions->length > 0) {
222 $condition = $conditions->item(0);
224 $start = $condition->getAttribute(
'NotBefore');
225 $end = $condition->getAttribute(
'NotOnOrAfter');
227 if ($start &&
$end) {
228 if (!self::checkDateConditions($start,
$end)) {
229 error_log(
'Date check failed ... (from ' . $start .
' to ' .
$end .
')');
235 $attribute_nodes = $this->
doXPathQuery(
'shib:AttributeStatement/shib:Attribute/shib:AttributeValue', $assertion);
237 foreach ($attribute_nodes as $attribute) {
238 $value = $attribute->textContent;
239 $name = $attribute->parentNode->getAttribute(
'AttributeName');
241 if ($attribute->hasAttribute(
'Scope')) {
242 $scopePart =
'@' . $attribute->getAttribute(
'Scope');
247 if (!is_string(
$name)) {
248 throw new \Exception(
'Shib13 Attribute node without an AttributeName.');
256 $encodedvalues = explode(
'_', $value);
257 foreach ($encodedvalues as $v) {
272 $query =
'/shibp:Response/shib:Assertion/@Issuer';
275 if ($attr = $nodelist->item(0)) {
278 throw new \Exception(
'Could not find Issuer field in Authentication response');
286 $query =
'/shibp:Response/shib:Assertion/shib:AuthenticationStatement/shib:Subject/shib:NameIdentifier';
289 if ($node = $nodelist->item(0)) {
290 $nameID[
"Value"] = $node->nodeValue;
291 $nameID[
"Format"] = $node->getAttribute(
'Format');
309 assert(
'is_string($shire)');
310 assert(
'$attributes === NULL || is_array($attributes)');
312 if ($sp->
hasValue(
'scopedattributes')) {
313 $scopedAttributes = $sp->
getArray(
'scopedattributes');
314 } elseif ($idp->
hasValue(
'scopedattributes')) {
315 $scopedAttributes = $idp->
getArray(
'scopedattributes');
317 $scopedAttributes =
array();
334 $base64 = $sp->
getBoolean(
'base64attributes',
false);
341 ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' .
342 ' NameQualifier="' . htmlspecialchars($namequalifier) .
'"' .
345 '</NameIdentifier>' .
346 '<SubjectConfirmation>' .
347 '<ConfirmationMethod>' .
348 'urn:oasis:names:tc:SAML:1.0:cm:bearer' .
349 '</ConfirmationMethod>' .
350 '</SubjectConfirmation>' .
353 $encodedattributes =
'';
356 $encodedattributes .=
'<AttributeStatement>';
357 $encodedattributes .= $subjectNode;
360 $encodedattributes .= $this->
enc_attribute(
$name, $value, $base64, $scopedAttributes);
363 $encodedattributes .=
'</AttributeStatement>';
369 $response =
'<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol" 370 xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" 371 xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 372 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant.
'" 373 MajorVersion="1" MinorVersion="1" 374 Recipient="' . htmlspecialchars($shire) .
'" ResponseID="' .
$id .
'"> 376 <StatusCode Value="samlp:Success" /> 378 <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" 379 AssertionID="' . $assertionid .
'" IssueInstant="' . $issueInstant.
'" 380 Issuer="' . htmlspecialchars($idp->
getString(
'entityid')) .
'" MajorVersion="1" MinorVersion="1"> 381 <Conditions NotBefore="' . $notBefore.
'" NotOnOrAfter="'. $assertionExpire .
'"> 382 <AudienceRestrictionCondition> 383 <Audience>' . htmlspecialchars($audience) .
'</Audience> 384 </AudienceRestrictionCondition> 386 <AuthenticationStatement AuthenticationInstant="' . $issueInstant.
'" 387 AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' .
389 </AuthenticationStatement> 390 ' . $encodedattributes .
' 409 assert(
'is_string($name)');
410 assert(
'is_array($values)');
411 assert(
'is_bool($base64)');
412 assert(
'is_array($scopedAttributes)');
414 if (in_array(
$name, $scopedAttributes,
true)) {
420 $attr =
'<Attribute AttributeName="' . htmlspecialchars(
$name) .
'" AttributeNamespace="urn:mace:shibboleth:1.0:attributeNamespace:uri">';
421 foreach ($values as $value) {
424 $tmp = explode(
'@', $value, 2);
425 if (count($tmp) === 2) {
427 $scopePart =
' Scope="' . htmlspecialchars($tmp[1]) .
'"';
432 $value = base64_encode($value);
435 $attr .=
'<AttributeValue' . $scopePart .
'>' . htmlspecialchars($value) .
'</AttributeValue>';
437 $attr .=
'</Attribute>';
461 $currentTime =
time();
463 if (!empty($start)) {
466 if (($startTime < 0) || (($startTime - 600) > $currentTime)) {
472 if (($endTime < 0) || ($endTime <= $currentTime)) {
static generateID()
Generate a random identifier, ID_LENGTH bytes long.
generate(\SimpleSAML_Configuration $idp, \SimpleSAML_Configuration $sp, $shire, $attributes)
Build a authentication response.
getArray($name, $default=self::REQUIRED_OPTION)
This function retrieves an array configuration option.
isNodeValidated($node)
Checks if the given node is validated by the signature on this response.
hasValue($name)
Check whether a key in the configuration exists or not.
if(!array_key_exists('StateId', $_REQUEST)) $id
enc_attribute($name, $values, $base64, $scopedAttributes)
Format a shib13 attribute.
setMessageValidated($messageValidated)
Set whether this message was validated externally.
$metadata['__DYNAMIC:1__']
static generateTimestamp($instant=null)
This function generates a timestamp on the form used by the SAML protocols.
getBoolean($name, $default=self::REQUIRED_OPTION)
This function retrieves a boolean configuration option.
catch(Exception $e) if(!($request instanceof \SAML2\ArtifactResolve)) $issuer
Create styles array
The data for the language used.
static xsDateTimeToTimestamp($time)
This function converts a SAML2 timestamp on the form yyyy-mm-ddThh:mm:ss(.s+)?Z to a UNIX timestamp...
getString($name, $default=self::REQUIRED_OPTION)
This function retrieves a string configuration option.
static checkDateConditions($start=null, $end=null)
Check if we are currently between the given date & time conditions.
static getCertPath($path)
Resolves a path that may be relative to the cert-directory.
setRelayState($relayState)
getSessionIndex()
Retrieve the session index of this response.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
doXPathQuery($query, $node=null)
This function runs an xPath query on this authentication response.