1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace SimpleSAML\Module\casserver\Cas\Protocol; |
6
|
|
|
|
7
|
|
|
use SimpleSAML\Configuration; |
8
|
|
|
use SimpleSAML\Module\casserver\Shib13\AuthnResponse; |
9
|
|
|
use SimpleSAML\SOAP\XML\env_200106\Body; |
10
|
|
|
use SimpleSAML\SOAP\XML\env_200106\Envelope; |
11
|
|
|
use SimpleSAML\XML\Chunk; |
12
|
|
|
use SimpleSAML\XML\DOMDocumentFactory; |
13
|
|
|
use SimpleSAML\XML\SerializableElementInterface; |
14
|
|
|
|
15
|
|
|
class SamlValidateResponder |
16
|
|
|
{ |
17
|
|
|
/** |
18
|
|
|
* Converts a ticket to saml1 response. Caller likely needs wrap in SOAP |
19
|
|
|
* to return to a client. |
20
|
|
|
* @param array $ticket The cas ticket |
21
|
|
|
* @return \SimpleSAML\XML\Chunk The saml 1 xml for the CAS response |
22
|
|
|
*/ |
23
|
|
|
public function convertToSaml(array $ticket): Chunk |
24
|
|
|
{ |
25
|
|
|
$serviceUrl = $ticket['service']; |
26
|
|
|
$attributes = $ticket['attributes']; |
27
|
|
|
$user = $ticket['userName']; |
28
|
|
|
|
29
|
|
|
$ar = new AuthnResponse(); |
30
|
|
|
$idpMetadata = [ |
31
|
|
|
// CAS doesn't seem to care what this is, however SSP code requires it to be set |
32
|
|
|
'entityid' => 'localhost', |
33
|
|
|
]; |
34
|
|
|
$spMetadata = [ |
35
|
|
|
'entityid' => $serviceUrl, |
36
|
|
|
]; |
37
|
|
|
$shire = $serviceUrl; //the recpient |
38
|
|
|
$authnResponseXML = $ar->generate( |
39
|
|
|
Configuration::loadFromArray($idpMetadata), |
40
|
|
|
Configuration::loadFromArray($spMetadata), |
41
|
|
|
$shire, |
42
|
|
|
$attributes, |
43
|
|
|
); |
44
|
|
|
|
45
|
|
|
// replace NameIdentifier with actually username |
46
|
|
|
$ret = preg_replace( |
47
|
|
|
'|<NameIdentifier(.*)>.*</NameIdentifier>|', |
48
|
|
|
'<NameIdentifier$1>' . htmlspecialchars($user) . '</NameIdentifier>', |
49
|
|
|
$authnResponseXML, |
50
|
|
|
); |
51
|
|
|
// CAS seems to prefer this type of assertiond |
52
|
|
|
$ret = str_replace('urn:oasis:names:tc:SAML:1.0:cm:bearer', 'urn:oasis:names:tc:SAML:1.0:cm:artifact', $ret); |
53
|
|
|
// CAS uses a different namespace for attributes |
54
|
|
|
$ret = str_replace( |
55
|
|
|
'urn:mace:shibboleth:1.0:attributeNamespace:uri', |
56
|
|
|
'http://www.ja-sig.org/products/cas/', |
57
|
|
|
$ret, |
58
|
|
|
); |
59
|
|
|
|
60
|
|
|
$doc = DOMDocumentFactory::fromString($ret); |
61
|
|
|
return new Chunk($doc->documentElement); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @param \SimpleSAML\XML\SerializableElementInterface $samlResponse |
67
|
|
|
* @return \SimpleSAML\SOAP\XML\env_200106\Envelope |
68
|
|
|
*/ |
69
|
|
|
public function wrapInSoap(SerializableElementInterface $samlResponse): Envelope |
70
|
|
|
{ |
71
|
|
|
$body = new Body([$samlResponse]); |
72
|
|
|
return new Envelope($body); |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|