Skip to content

Commit 3f8017f

Browse files
committed
N°7046 Fix authent-cas: "CAS_ServiceBaseUrl_Static" not found
Regression in 3.1.0 brought by N°5270 (02afa2f)
1 parent 4846532 commit 3f8017f

File tree

7 files changed

+390
-2
lines changed

7 files changed

+390
-2
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
3+
/**
4+
* Licensed to Jasig under one or more contributor license
5+
* agreements. See the NOTICE file distributed with this work for
6+
* additional information regarding copyright ownership.
7+
*
8+
* Jasig licenses this file to you under the Apache License,
9+
* Version 2.0 (the "License"); you may not use this file except in
10+
* compliance with the License. You may obtain a copy of the License at:
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*
20+
* PHP Version 7
21+
*
22+
* @file CAS/ServiceBaseUrl/AllowedListDiscovery.php
23+
* @category Authentication
24+
* @package PhpCAS
25+
* @author Henry Pan <git@phy25.com>
26+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
27+
* @link https://wiki.jasig.org/display/CASC/phpCAS
28+
*/
29+
30+
31+
/**
32+
* Class that gets the service base URL of the PHP server by HTTP header
33+
* discovery and allowlist check. This is used to generate service URL
34+
* and PGT callback URL.
35+
*
36+
* @class CAS_ServiceBaseUrl_AllowedListDiscovery
37+
* @category Authentication
38+
* @package PhpCAS
39+
* @author Henry Pan <git@phy25.com>
40+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
41+
* @link https://wiki.jasig.org/display/CASC/phpCAS
42+
*/
43+
44+
class CAS_ServiceBaseUrl_AllowedListDiscovery
45+
extends CAS_ServiceBaseUrl_Base
46+
{
47+
private $_list = array();
48+
49+
public function __construct($list) {
50+
if (is_array($list)) {
51+
if (count($list) === 0) {
52+
throw new CAS_InvalidArgumentException('$list should not be empty');
53+
}
54+
foreach ($list as $value) {
55+
$this->allow($value);
56+
}
57+
} else {
58+
throw new CAS_TypeMismatchException($list, '$list', 'array');
59+
}
60+
}
61+
62+
/**
63+
* Add a base URL to the allowed list.
64+
*
65+
* @param $url protocol, host name and port to add to the allowed list
66+
*
67+
* @return void
68+
*/
69+
public function allow($url)
70+
{
71+
$this->_list[] = $this->removeStandardPort($url);
72+
}
73+
74+
/**
75+
* Check if the server name is allowed by configuration.
76+
*
77+
* @param $name server name to check
78+
*
79+
* @return bool whether the allowed list contains the server name
80+
*/
81+
protected function isAllowed($name)
82+
{
83+
return in_array($name, $this->_list);
84+
}
85+
86+
/**
87+
* Discover the server name through HTTP headers.
88+
*
89+
* We read:
90+
* - HTTP header X-Forwarded-Host
91+
* - HTTP header X-Forwarded-Server and X-Forwarded-Port
92+
* - HTTP header Host and SERVER_PORT
93+
* - PHP SERVER_NAME (which can change based on the HTTP server used)
94+
*
95+
* The standard port will be omitted (80 for HTTP, 443 for HTTPS).
96+
*
97+
* @return string the discovered, unsanitized server protocol, hostname and port
98+
*/
99+
protected function discover()
100+
{
101+
$isHttps = $this->isHttps();
102+
$protocol = $isHttps ? 'https' : 'http';
103+
$protocol .= '://';
104+
if (!empty($_SERVER['HTTP_X_FORWARDED_HOST'])) {
105+
// explode the host list separated by comma and use the first host
106+
$hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
107+
// see rfc7239#5.3 and rfc7230#2.7.1: port is in HTTP_X_FORWARDED_HOST if non default
108+
return $protocol . $hosts[0];
109+
} else if (!empty($_SERVER['HTTP_X_FORWARDED_SERVER'])) {
110+
$server_url = $_SERVER['HTTP_X_FORWARDED_SERVER'];
111+
} else {
112+
if (empty($_SERVER['SERVER_NAME'])) {
113+
$server_url = $_SERVER['HTTP_HOST'];
114+
} else {
115+
$server_url = $_SERVER['SERVER_NAME'];
116+
}
117+
}
118+
if (!strpos($server_url, ':')) {
119+
if (empty($_SERVER['HTTP_X_FORWARDED_PORT'])) {
120+
$server_port = $_SERVER['SERVER_PORT'];
121+
} else {
122+
$ports = explode(',', $_SERVER['HTTP_X_FORWARDED_PORT']);
123+
$server_port = $ports[0];
124+
}
125+
126+
$server_url .= ':';
127+
$server_url .= $server_port;
128+
}
129+
return $protocol . $server_url;
130+
}
131+
132+
/**
133+
* Get PHP server base URL.
134+
*
135+
* @return string the server protocol, hostname and port
136+
*/
137+
public function get()
138+
{
139+
phpCAS::traceBegin();
140+
$result = $this->removeStandardPort($this->discover());
141+
phpCAS::trace("Discovered server base URL: " . $result);
142+
if ($this->isAllowed($result)) {
143+
phpCAS::trace("Server base URL is allowed");
144+
phpCAS::traceEnd(true);
145+
} else {
146+
$result = $this->_list[0];
147+
phpCAS::trace("Server base URL is not allowed, using default: " . $result);
148+
phpCAS::traceEnd(false);
149+
}
150+
return $result;
151+
}
152+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
/**
4+
* Licensed to Jasig under one or more contributor license
5+
* agreements. See the NOTICE file distributed with this work for
6+
* additional information regarding copyright ownership.
7+
*
8+
* Jasig licenses this file to you under the Apache License,
9+
* Version 2.0 (the "License"); you may not use this file except in
10+
* compliance with the License. You may obtain a copy of the License at:
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*
20+
* PHP Version 7
21+
*
22+
* @file CAS/ServiceBaseUrl/Base.php
23+
* @category Authentication
24+
* @package PhpCAS
25+
* @author Henry Pan <git@phy25.com>
26+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
27+
* @link https://wiki.jasig.org/display/CASC/phpCAS
28+
*/
29+
30+
/**
31+
* Base class of CAS/ServiceBaseUrl that implements isHTTPS method.
32+
*
33+
* @class CAS_ServiceBaseUrl_Base
34+
* @category Authentication
35+
* @package PhpCAS
36+
* @author Henry Pan <git@phy25.com>
37+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
38+
* @link https://wiki.jasig.org/display/CASC/phpCAS
39+
*/
40+
abstract class CAS_ServiceBaseUrl_Base
41+
implements CAS_ServiceBaseUrl_Interface
42+
{
43+
44+
/**
45+
* Get PHP server name.
46+
*
47+
* @return string the server hostname and port of the server
48+
*/
49+
abstract public function get();
50+
51+
/**
52+
* Check whether HTTPS is used.
53+
*
54+
* This is used to construct the protocol in the URL.
55+
*
56+
* @return bool true if HTTPS is used
57+
*/
58+
public function isHttps() {
59+
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
60+
return ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https');
61+
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTOCOL'])) {
62+
return ($_SERVER['HTTP_X_FORWARDED_PROTOCOL'] === 'https');
63+
} elseif ( isset($_SERVER['HTTPS'])
64+
&& !empty($_SERVER['HTTPS'])
65+
&& strcasecmp($_SERVER['HTTPS'], 'off') !== 0
66+
) {
67+
return true;
68+
}
69+
return false;
70+
}
71+
72+
/**
73+
* Remove standard HTTP and HTTPS port for discovery and allowlist input.
74+
*
75+
* @param $url URL as https://domain:port without trailing slash
76+
* @return standardized URL, or the original URL
77+
* @throws CAS_InvalidArgumentException if the URL does not include the protocol
78+
*/
79+
protected function removeStandardPort($url) {
80+
if (strpos($url, "://") === false) {
81+
throw new CAS_InvalidArgumentException(
82+
"Configured base URL should include the protocol string: " . $url);
83+
}
84+
85+
$url = rtrim($url, '/');
86+
87+
if (strpos($url, "https://") === 0 && substr_compare($url, ':443', -4) === 0) {
88+
return substr($url, 0, -4);
89+
}
90+
91+
if (strpos($url, "http://") === 0 && substr_compare($url, ':80', -3) === 0) {
92+
return substr($url, 0, -3);
93+
}
94+
95+
return $url;
96+
}
97+
98+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/**
4+
* Licensed to Jasig under one or more contributor license
5+
* agreements. See the NOTICE file distributed with this work for
6+
* additional information regarding copyright ownership.
7+
*
8+
* Jasig licenses this file to you under the Apache License,
9+
* Version 2.0 (the "License"); you may not use this file except in
10+
* compliance with the License. You may obtain a copy of the License at:
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*
20+
* PHP Version 7
21+
*
22+
* @file CAS/ServerHostname/Interface.php
23+
* @category Authentication
24+
* @package PhpCAS
25+
* @author Henry Pan <git@phy25.com>
26+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
27+
* @link https://wiki.jasig.org/display/CASC/phpCAS
28+
*/
29+
30+
/**
31+
* An interface for classes that gets the server name of the PHP server.
32+
* This is used to generate service URL and PGT callback URL.
33+
*
34+
* @class CAS_ServiceBaseUrl_Interface
35+
* @category Authentication
36+
* @package PhpCAS
37+
* @author Henry Pan <git@phy25.com>
38+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
39+
* @link https://wiki.jasig.org/display/CASC/phpCAS
40+
*/
41+
interface CAS_ServiceBaseUrl_Interface
42+
{
43+
44+
/**
45+
* Get PHP HTTP protocol and server name.
46+
*
47+
* @return string protocol, server hostname, and optionally port,
48+
* without trailing slash (https://localhost:8443)
49+
*/
50+
public function get();
51+
52+
/**
53+
* Check whether HTTPS is used.
54+
*
55+
* This is used to construct the protocol in the URL.
56+
*
57+
* @return bool true if HTTPS is used
58+
*/
59+
public function isHttps();
60+
61+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/**
4+
* Licensed to Jasig under one or more contributor license
5+
* agreements. See the NOTICE file distributed with this work for
6+
* additional information regarding copyright ownership.
7+
*
8+
* Jasig licenses this file to you under the Apache License,
9+
* Version 2.0 (the "License"); you may not use this file except in
10+
* compliance with the License. You may obtain a copy of the License at:
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*
20+
* PHP Version 7
21+
*
22+
* @file CAS/ServiceBaseUrl/Static.php
23+
* @category Authentication
24+
* @package PhpCAS
25+
* @author Henry Pan <git@phy25.com>
26+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
27+
* @link https://wiki.jasig.org/display/CASC/phpCAS
28+
*/
29+
30+
31+
/**
32+
* Class that gets the server name of the PHP server by statically set
33+
* hostname and port. This is used to generate service URL and PGT
34+
* callback URL.
35+
*
36+
* @class CAS_ServiceBaseUrl_Static
37+
* @category Authentication
38+
* @package PhpCAS
39+
* @author Henry Pan <git@phy25.com>
40+
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
41+
* @link https://wiki.jasig.org/display/CASC/phpCAS
42+
*/
43+
44+
class CAS_ServiceBaseUrl_Static
45+
extends CAS_ServiceBaseUrl_Base
46+
{
47+
private $_name = null;
48+
49+
public function __construct($name) {
50+
if (is_string($name)) {
51+
$this->_name = $this->removeStandardPort($name);
52+
} else {
53+
throw new CAS_TypeMismatchException($name, '$name', 'string');
54+
}
55+
}
56+
57+
/**
58+
* Get the server name through static config.
59+
*
60+
* @return string the server hostname and port of the server configured
61+
*/
62+
public function get()
63+
{
64+
phpCAS::traceBegin();
65+
phpCAS::trace("Returning static server name: " . $this->_name);
66+
phpCAS::traceEnd(true);
67+
return $this->_name;
68+
}
69+
}

lib/composer/autoload_classmap.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@
145145
'CAS_Request_Exception' => $vendorDir . '/apereo/phpcas/source/CAS/Request/Exception.php',
146146
'CAS_Request_MultiRequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/MultiRequestInterface.php',
147147
'CAS_Request_RequestInterface' => $vendorDir . '/apereo/phpcas/source/CAS/Request/RequestInterface.php',
148+
'CAS_ServiceBaseUrl_AllowedListDiscovery' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/AllowedListDiscovery.php',
149+
'CAS_ServiceBaseUrl_Base' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Base.php',
150+
'CAS_ServiceBaseUrl_Interface' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Interface.php',
151+
'CAS_ServiceBaseUrl_Static' => $vendorDir . '/apereo/phpcas/source/CAS/ServiceBaseUrl/Static.php',
148152
'CAS_Session_PhpSession' => $vendorDir . '/apereo/phpcas/source/CAS/Session/PhpSession.php',
149153
'CAS_TypeMismatchException' => $vendorDir . '/apereo/phpcas/source/CAS/TypeMismatchException.php',
150154
'CLILikeWebPage' => $baseDir . '/sources/Application/WebPage/CLILikeWebPage.php',

0 commit comments

Comments
 (0)