File: attributeserver.php

package info (click to toggle)
simplesamlphp 1.19.7-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 42,920 kB
  • sloc: php: 202,044; javascript: 14,867; xml: 2,700; sh: 225; perl: 82; makefile: 70; python: 5
file content (93 lines) | stat: -rw-r--r-- 3,506 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php

$metadata = \SimpleSAML\Metadata\MetaDataStorageHandler::getMetadataHandler();

$binding = \SAML2\Binding::getCurrentBinding();
$query = $binding->receive();
if (!($query instanceof \SAML2\AttributeQuery)) {
    throw new \SimpleSAML\Error\BadRequest('Invalid message received to AttributeQuery endpoint.');
}

$idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');

$issuer = $query->getIssuer();
if ($issuer === null) {
    throw new \SimpleSAML\Error\BadRequest('Missing <saml:Issuer> in <samlp:AttributeQuery>.');
} elseif (is_string($issuer)) {
    $spEntityId = $issuer;
} else {
    $spEntityId = $issuer->getValue();
}

$idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted');
$spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');

// The endpoint we should deliver the message to
$endpoint = $spMetadata->getString('testAttributeEndpoint');

// The attributes we will return
$attributes = [
    'name' => ['value1', 'value2', 'value3'],
    'test' => ['test'],
];

// The name format of the attributes
$attributeNameFormat = \SAML2\Constants::NAMEFORMAT_UNSPECIFIED;

// Determine which attributes we will return
$returnAttributes = array_keys($query->getAttributes());
if (count($returnAttributes) === 0) {
    SimpleSAML\Logger::debug('No attributes requested - return all attributes.');
    $returnAttributes = $attributes;
} elseif ($query->getAttributeNameFormat() !== $attributeNameFormat) {
    SimpleSAML\Logger::debug('Requested attributes with wrong NameFormat - no attributes returned.');
    $returnAttributes = [];
} else {
    foreach ($returnAttributes as $name => $values) {
        /** @var array $values */
        if (!array_key_exists($name, $attributes)) {
            // We don't have this attribute
            unset($returnAttributes[$name]);
            continue;
        }
        if (count($values) === 0) {
            // Return all attributes
            $returnAttributes[$name] = $attributes[$name];
            continue;
        }

        // Filter which attribute values we should return
        $returnAttributes[$name] = array_intersect($values, $attributes[$name]);
    }
}

// $returnAttributes contains the attributes we should return. Send them
$assertion = new \SAML2\Assertion();
$assertion->setIssuer($idpEntityId);
$assertion->setNameId($query->getNameId());
$assertion->setNotBefore(time());
$assertion->setNotOnOrAfter(time() + 300); // 60*5 = 5min
$assertion->setValidAudiences([$spEntityId]);
$assertion->setAttributes($returnAttributes);
$assertion->setAttributeNameFormat($attributeNameFormat);

$sc = new \SAML2\XML\saml\SubjectConfirmation();
$sc->Method = \SAML2\Constants::CM_BEARER;
$sc->SubjectConfirmationData = new \SAML2\XML\saml\SubjectConfirmationData();
$sc->SubjectConfirmationData->setNotOnOrAfter(time() + 300); // 60*5 = 5min
$sc->SubjectConfirmationData->setRecipient($endpoint);
$sc->SubjectConfirmationData->setInResponseTo($query->getId());
$assertion->setSubjectConfirmation([$sc]);

\SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $assertion);

$response = new \SAML2\Response();
$response->setRelayState($query->getRelayState());
$response->setDestination($endpoint);
$response->setIssuer($idpEntityId);
$response->setInResponseTo($query->getId());
$response->setAssertions([$assertion]);
\SimpleSAML\Module\saml\Message::addSign($idpMetadata, $spMetadata, $response);

$binding = new \SAML2\HTTPPost();
$binding->send($response);