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.
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:
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * Interface class of the phpCAS library
26 * @category Authentication
28 * @author Pascal Aubry <pascal.aubry@univ-rennes1.fr>
29 * @author Olivier Berger <olivier.berger@it-sudparis.eu>
30 * @author Brett Bieber <brett.bieber@gmail.com>
31 * @author Joachim Fritschi <jfritschi@freenet.de>
32 * @author Adam Franco <afranco@middlebury.edu>
33 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
34 * @link https://wiki.jasig.org/display/CASC/phpCAS
40 // hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI']
43 if (php_sapi_name() != 'cli') {
44 if (!isset($_SERVER['REQUEST_URI'])) {
45 $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
49 // Add a E_USER_DEPRECATED for php versions <= 5.2
50 if (!defined('E_USER_DEPRECATED')) {
51 define('E_USER_DEPRECATED', E_USER_NOTICE);
55 // ########################################################################
57 // ########################################################################
59 // ------------------------------------------------------------------------
61 // ------------------------------------------------------------------------
64 * phpCAS version. accessible for the user by phpCAS::getVersion().
66 define('PHPCAS_VERSION', '1.3.2');
76 define("CAS_VERSION_1_0", '1.0');
80 define("CAS_VERSION_2_0", '2.0');
82 // ------------------------------------------------------------------------
84 // ------------------------------------------------------------------------
89 define("SAML_VERSION_1_1", 'S1');
92 * XML header for SAML POST
94 define("SAML_XML_HEADER", '<?xml version="1.0" encoding="UTF-8"?>');
97 * SOAP envelope for SAML POST
99 define("SAML_SOAP_ENV", '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/>');
102 * SOAP body for SAML POST
104 define("SAML_SOAP_BODY", '<SOAP-ENV:Body>');
109 define("SAMLP_REQUEST", '<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" MajorVersion="1" MinorVersion="1" RequestID="_192.168.16.51.1024506224022" IssueInstant="2002-06-19T17:03:44.022Z">');
110 define("SAMLP_REQUEST_CLOSE", '</samlp:Request>');
113 * SAMLP artifact tag (for the ticket)
115 define("SAML_ASSERTION_ARTIFACT", '<samlp:AssertionArtifact>');
120 define("SAML_ASSERTION_ARTIFACT_CLOSE", '</samlp:AssertionArtifact>');
125 define("SAML_SOAP_BODY_CLOSE", '</SOAP-ENV:Body>');
128 * SOAP envelope close
130 define("SAML_SOAP_ENV_CLOSE", '</SOAP-ENV:Envelope>');
135 define("SAML_ATTRIBUTES", 'SAMLATTRIBS');
139 * @addtogroup publicPGTStorage
142 // ------------------------------------------------------------------------
144 // ------------------------------------------------------------------------
146 * Default path used when storing PGT's to file
148 define("CAS_PGT_STORAGE_FILE_DEFAULT_PATH", session_save_path());
150 // ------------------------------------------------------------------------
151 // SERVICE ACCESS ERRORS
152 // ------------------------------------------------------------------------
154 * @addtogroup publicServices
159 * phpCAS::service() error code on success
161 define("PHPCAS_SERVICE_OK", 0);
163 * phpCAS::service() error code when the PT could not retrieve because
164 * the CAS server did not respond.
166 define("PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE", 1);
168 * phpCAS::service() error code when the PT could not retrieve because
169 * the response of the CAS server was ill-formed.
171 define("PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE", 2);
173 * phpCAS::service() error code when the PT could not retrieve because
174 * the CAS server did not want to.
176 define("PHPCAS_SERVICE_PT_FAILURE", 3);
178 * phpCAS::service() error code when the service was not available.
180 define("PHPCAS_SERVICE_NOT_AVAILABLE", 4);
182 // ------------------------------------------------------------------------
184 // ------------------------------------------------------------------------
186 * phpCAS::getProxiedService() type for HTTP GET
188 define("PHPCAS_PROXIED_SERVICE_HTTP_GET", 'CAS_ProxiedService_Http_Get');
190 * phpCAS::getProxiedService() type for HTTP POST
192 define("PHPCAS_PROXIED_SERVICE_HTTP_POST", 'CAS_ProxiedService_Http_Post');
194 * phpCAS::getProxiedService() type for IMAP
196 define("PHPCAS_PROXIED_SERVICE_IMAP", 'CAS_ProxiedService_Imap');
200 // ------------------------------------------------------------------------
202 // ------------------------------------------------------------------------
204 * @addtogroup publicLang
208 define("PHPCAS_LANG_ENGLISH", 'CAS_Languages_English');
209 define("PHPCAS_LANG_FRENCH", 'CAS_Languages_French');
210 define("PHPCAS_LANG_GREEK", 'CAS_Languages_Greek');
211 define("PHPCAS_LANG_GERMAN", 'CAS_Languages_German');
212 define("PHPCAS_LANG_JAPANESE", 'CAS_Languages_Japanese');
213 define("PHPCAS_LANG_SPANISH", 'CAS_Languages_Spanish');
214 define("PHPCAS_LANG_CATALAN", 'CAS_Languages_Catalan');
219 * @addtogroup internalLang
224 * phpCAS default language (when phpCAS::setLang() is not used)
226 define("PHPCAS_LANG_DEFAULT", PHPCAS_LANG_ENGLISH);
229 // ------------------------------------------------------------------------
231 // ------------------------------------------------------------------------
233 * @addtogroup publicDebug
238 * The default directory for the debug file under Unix.
240 define('DEFAULT_DEBUG_DIR', '/tmp/');
244 // include the class autoloader
245 require_once dirname(__FILE__) . '/CAS/Autoload.php';
248 * The phpCAS class is a simple container for the phpCAS library. It provides CAS
249 * authentication for web applications written in PHP.
253 * @category Authentication
255 * @author Pascal Aubry <pascal.aubry@univ-rennes1.fr>
256 * @author Olivier Berger <olivier.berger@it-sudparis.eu>
257 * @author Brett Bieber <brett.bieber@gmail.com>
258 * @author Joachim Fritschi <jfritschi@freenet.de>
259 * @author Adam Franco <afranco@middlebury.edu>
260 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
261 * @link https://wiki.jasig.org/display/CASC/phpCAS
268 * This variable is used by the interface class phpCAS.
272 private static $_PHPCAS_CLIENT;
275 * This variable is used to store where the initializer is called from
276 * (to print a comprehensive error in case of multiple calls).
280 private static $_PHPCAS_INIT_CALL;
283 * This variable is used to store phpCAS debug mode.
287 private static $_PHPCAS_DEBUG;
290 // ########################################################################
292 // ########################################################################
295 * @addtogroup publicInit
300 * phpCAS client initializer.
302 * @param string $server_version the version of the CAS server
303 * @param string $server_hostname the hostname of the CAS server
304 * @param string $server_port the port the CAS server is running on
305 * @param string $server_uri the URI the CAS server is responding on
306 * @param bool $changeSessionID Allow phpCAS to change the session_id (Single
307 * Sign Out/handleLogoutRequests is based on that change)
309 * @return a newly created CAS_Client object
310 * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
311 * called, only once, and before all other methods (except phpCAS::getVersion()
312 * and phpCAS::setDebug()).
314 public static function client($server_version, $server_hostname,
315 $server_port, $server_uri, $changeSessionID = true
317 phpCAS :: traceBegin();
318 if (is_object(self::$_PHPCAS_CLIENT)) {
319 phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
321 if (gettype($server_version) != 'string') {
322 phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');
324 if (gettype($server_hostname) != 'string') {
325 phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');
327 if (gettype($server_port) != 'integer') {
328 phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');
330 if (gettype($server_uri) != 'string') {
331 phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');
334 // store where the initializer is called from
335 $dbg = debug_backtrace();
336 self::$_PHPCAS_INIT_CALL = array (
338 'file' => $dbg[0]['file'],
339 'line' => $dbg[0]['line'],
340 'method' => __CLASS__ . '::' . __FUNCTION__
343 // initialize the object $_PHPCAS_CLIENT
344 self::$_PHPCAS_CLIENT = new CAS_Client(
345 $server_version, false, $server_hostname, $server_port, $server_uri,
348 phpCAS :: traceEnd();
352 * phpCAS proxy initializer.
354 * @param string $server_version the version of the CAS server
355 * @param string $server_hostname the hostname of the CAS server
356 * @param string $server_port the port the CAS server is running on
357 * @param string $server_uri the URI the CAS server is responding on
358 * @param bool $changeSessionID Allow phpCAS to change the session_id (Single
359 * Sign Out/handleLogoutRequests is based on that change)
361 * @return a newly created CAS_Client object
362 * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
363 * called, only once, and before all other methods (except phpCAS::getVersion()
364 * and phpCAS::setDebug()).
366 public static function proxy($server_version, $server_hostname,
367 $server_port, $server_uri, $changeSessionID = true
369 phpCAS :: traceBegin();
370 if (is_object(self::$_PHPCAS_CLIENT)) {
371 phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')');
373 if (gettype($server_version) != 'string') {
374 phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');
376 if (gettype($server_hostname) != 'string') {
377 phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');
379 if (gettype($server_port) != 'integer') {
380 phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');
382 if (gettype($server_uri) != 'string') {
383 phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');
386 // store where the initialzer is called from
387 $dbg = debug_backtrace();
388 self::$_PHPCAS_INIT_CALL = array (
390 'file' => $dbg[0]['file'],
391 'line' => $dbg[0]['line'],
392 'method' => __CLASS__ . '::' . __FUNCTION__
395 // initialize the object $_PHPCAS_CLIENT
396 self::$_PHPCAS_CLIENT = new CAS_Client(
397 $server_version, true, $server_hostname, $server_port, $server_uri,
400 phpCAS :: traceEnd();
404 // ########################################################################
406 // ########################################################################
409 * @addtogroup publicDebug
414 * Set/unset debug mode
416 * @param string $filename the name of the file used for logging, or false
421 public static function setDebug($filename = '')
423 if ($filename != false && gettype($filename) != 'string') {
424 phpCAS :: error('type mismatched for parameter $dbg (should be false or the name of the log file)');
426 if ($filename === false) {
427 self::$_PHPCAS_DEBUG['filename'] = false;
430 if (empty ($filename)) {
431 if (preg_match('/^Win.*/', getenv('OS'))) {
432 if (isset ($_ENV['TMP'])) {
433 $debugDir = $_ENV['TMP'] . '/';
438 $debugDir = DEFAULT_DEBUG_DIR;
440 $filename = $debugDir . 'phpCAS.log';
443 if (empty (self::$_PHPCAS_DEBUG['unique_id'])) {
444 self::$_PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4);
447 self::$_PHPCAS_DEBUG['filename'] = $filename;
448 self::$_PHPCAS_DEBUG['indent'] = 0;
450 phpCAS :: trace('START phpCAS-' . PHPCAS_VERSION . ' ******************');
456 * Logs a string in debug mode.
458 * @param string $str the string to write
463 public static function log($str)
468 if (!empty(self::$_PHPCAS_DEBUG['filename'])) {
469 // Check if file exists and modifiy file permissions to be only
470 // readable by the webserver
471 if (!file_exists(self::$_PHPCAS_DEBUG['filename'])) {
472 touch(self::$_PHPCAS_DEBUG['filename']);
473 // Chmod will fail on windows
474 @chmod(self::$_PHPCAS_DEBUG['filename'], 0600);
476 for ($i = 0; $i < self::$_PHPCAS_DEBUG['indent']; $i++) {
480 // allow for multiline output with proper identing. Usefull for
481 // dumping cas answers etc.
482 $str2 = str_replace("\n", "\n" . self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str, $str);
483 error_log(self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2 . "\n", 3, self::$_PHPCAS_DEBUG['filename']);
489 * This method is used by interface methods to print an error and where the
490 * function was originally called from.
492 * @param string $msg the message to print
497 public static function error($msg)
499 $dbg = debug_backtrace();
503 if (is_array($dbg)) {
504 for ($i = 1; $i < sizeof($dbg); $i++) {
505 if (is_array($dbg[$i]) && isset($dbg[$i]['class']) ) {
506 if ($dbg[$i]['class'] == __CLASS__) {
507 $function = $dbg[$i]['function'];
508 $file = $dbg[$i]['file'];
509 $line = $dbg[$i]['line'];
514 echo "<br />\n<b>phpCAS error</b>: <font color=\"FF0000\"><b>" . __CLASS__ . "::" . $function . '(): ' . htmlentities($msg) . "</b></font> in <b>" . $file . "</b> on line <b>" . $line . "</b><br />\n";
515 phpCAS :: trace($msg);
516 phpCAS :: traceEnd();
518 throw new CAS_GracefullTerminationException(__CLASS__ . "::" . $function . '(): ' . $msg);
522 * This method is used to log something in debug mode.
524 * @param string $str string to log
528 public static function trace($str)
530 $dbg = debug_backtrace();
531 phpCAS :: log($str . ' [' . basename($dbg[0]['file']) . ':' . $dbg[0]['line'] . ']');
535 * This method is used to indicate the start of the execution of a function in debug mode.
539 public static function traceBegin()
541 $dbg = debug_backtrace();
543 if (!empty ($dbg[1]['class'])) {
544 $str .= $dbg[1]['class'] . '::';
546 $str .= $dbg[1]['function'] . '(';
547 if (is_array($dbg[1]['args'])) {
548 foreach ($dbg[1]['args'] as $index => $arg) {
552 if (is_object($arg)) {
553 $str .= get_class($arg);
555 $str .= str_replace(array("\r\n", "\n", "\r"), "", var_export($arg, true));
559 if (isset($dbg[1]['file'])) {
560 $file = basename($dbg[1]['file']);
562 $file = 'unknown_file';
564 if (isset($dbg[1]['line'])) {
565 $line = $dbg[1]['line'];
567 $line = 'unknown_line';
569 $str .= ') [' . $file . ':' . $line . ']';
571 if (!isset(self::$_PHPCAS_DEBUG['indent'])) {
572 self::$_PHPCAS_DEBUG['indent'] = 0;
574 self::$_PHPCAS_DEBUG['indent']++;
579 * This method is used to indicate the end of the execution of a function in
582 * @param string $res the result of the function
586 public static function traceEnd($res = '')
588 if (empty(self::$_PHPCAS_DEBUG['indent'])) {
589 self::$_PHPCAS_DEBUG['indent'] = 0;
591 self::$_PHPCAS_DEBUG['indent']--;
593 $dbg = debug_backtrace();
595 if (is_object($res)) {
596 $str .= '<= ' . get_class($res);
598 $str .= '<= ' . str_replace(array("\r\n", "\n", "\r"), "", var_export($res, true));
605 * This method is used to indicate the end of the execution of the program
609 public static function traceExit()
611 phpCAS :: log('exit()');
612 while (self::$_PHPCAS_DEBUG['indent'] > 0) {
614 self::$_PHPCAS_DEBUG['indent']--;
619 // ########################################################################
620 // INTERNATIONALIZATION
621 // ########################################################################
623 * @addtogroup publicLang
628 * This method is used to set the language used by phpCAS.
630 * @param string $lang string representing the language.
634 * @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH
635 * @note Can be called only once.
637 public static function setLang($lang)
639 if (!is_object(self::$_PHPCAS_CLIENT)) {
640 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
642 if (gettype($lang) != 'string') {
643 phpCAS :: error('type mismatched for parameter $lang (should be `string\')');
645 self::$_PHPCAS_CLIENT->setLang($lang);
649 // ########################################################################
651 // ########################################################################
658 * This method returns the phpCAS version.
660 * @return the phpCAS version.
662 public static function getVersion()
664 return PHPCAS_VERSION;
668 // ########################################################################
670 // ########################################################################
672 * @addtogroup publicOutput
677 * This method sets the HTML header used for all outputs.
679 * @param string $header the HTML header.
683 public static function setHTMLHeader($header)
685 if (!is_object(self::$_PHPCAS_CLIENT)) {
686 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
688 if (gettype($header) != 'string') {
689 phpCAS :: error('type mismatched for parameter $header (should be `string\')');
691 self::$_PHPCAS_CLIENT->setHTMLHeader($header);
695 * This method sets the HTML footer used for all outputs.
697 * @param string $footer the HTML footer.
701 public static function setHTMLFooter($footer)
703 if (!is_object(self::$_PHPCAS_CLIENT)) {
704 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
706 if (gettype($footer) != 'string') {
707 phpCAS :: error('type mismatched for parameter $footer (should be `string\')');
709 self::$_PHPCAS_CLIENT->setHTMLFooter($footer);
713 // ########################################################################
715 // ########################################################################
717 * @addtogroup publicPGTStorage
722 * This method can be used to set a custom PGT storage object.
724 * @param CAS_PGTStorage $storage a PGT storage object that inherits from the
725 * CAS_PGTStorage class
729 public static function setPGTStorage($storage)
731 phpCAS :: traceBegin();
732 if (!is_object(self::$_PHPCAS_CLIENT)) {
733 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
735 if (!self::$_PHPCAS_CLIENT->isProxy()) {
736 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
738 if (self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
739 phpCAS :: error('this method should only be called before ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() (called at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ')');
741 if ( !($storage instanceof CAS_PGTStorage) ) {
742 phpCAS :: error('type mismatched for parameter $storage (should be a CAS_PGTStorage `object\')');
744 self::$_PHPCAS_CLIENT->setPGTStorage($storage);
745 phpCAS :: traceEnd();
749 * This method is used to tell phpCAS to store the response of the
750 * CAS server to PGT requests in a database.
752 * @param string $dsn_or_pdo a dsn string to use for creating a PDO
753 * object or a PDO object
754 * @param string $username the username to use when connecting to the
756 * @param string $password the password to use when connecting to the
758 * @param string $table the table to use for storing and retrieving
760 * @param string $driver_options any driver options to use when connecting
765 public static function setPGTStorageDb($dsn_or_pdo, $username='',
766 $password='', $table='', $driver_options=null
768 phpCAS :: traceBegin();
769 if (!is_object(self::$_PHPCAS_CLIENT)) {
770 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
772 if (!self::$_PHPCAS_CLIENT->isProxy()) {
773 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
775 if (self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
776 phpCAS :: error('this method should only be called before ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() (called at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ')');
778 if (gettype($username) != 'string') {
779 phpCAS :: error('type mismatched for parameter $username (should be `string\')');
781 if (gettype($password) != 'string') {
782 phpCAS :: error('type mismatched for parameter $password (should be `string\')');
784 if (gettype($table) != 'string') {
785 phpCAS :: error('type mismatched for parameter $table (should be `string\')');
787 self::$_PHPCAS_CLIENT->setPGTStorageDb($dsn_or_pdo, $username, $password, $table, $driver_options);
788 phpCAS :: traceEnd();
792 * This method is used to tell phpCAS to store the response of the
793 * CAS server to PGT requests onto the filesystem.
795 * @param string $path the path where the PGT's should be stored
799 public static function setPGTStorageFile($path = '')
801 phpCAS :: traceBegin();
802 if (!is_object(self::$_PHPCAS_CLIENT)) {
803 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
805 if (!self::$_PHPCAS_CLIENT->isProxy()) {
806 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
808 if (self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
809 phpCAS :: error('this method should only be called before ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() (called at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ')');
811 if (gettype($path) != 'string') {
812 phpCAS :: error('type mismatched for parameter $path (should be `string\')');
814 self::$_PHPCAS_CLIENT->setPGTStorageFile($path);
815 phpCAS :: traceEnd();
818 // ########################################################################
819 // ACCESS TO EXTERNAL SERVICES
820 // ########################################################################
822 * @addtogroup publicServices
827 * Answer a proxy-authenticated service handler.
829 * @param string $type The service type. One of
830 * PHPCAS_PROXIED_SERVICE_HTTP_GET; PHPCAS_PROXIED_SERVICE_HTTP_POST;
831 * PHPCAS_PROXIED_SERVICE_IMAP
833 * @return CAS_ProxiedService
834 * @throws InvalidArgumentException If the service type is unknown.
836 public static function getProxiedService ($type)
838 phpCAS :: traceBegin();
839 if (!is_object(self::$_PHPCAS_CLIENT)) {
840 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
842 if (!self::$_PHPCAS_CLIENT->isProxy()) {
843 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
845 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
846 phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
848 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
849 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
851 if (gettype($type) != 'string') {
852 phpCAS :: error('type mismatched for parameter $type (should be `string\')');
855 $res = self::$_PHPCAS_CLIENT->getProxiedService($type);
857 phpCAS :: traceEnd();
862 * Initialize a proxied-service handler with the proxy-ticket it should use.
864 * @param CAS_ProxiedService $proxiedService Proxied Service Handler
867 * @throws CAS_ProxyTicketException If there is a proxy-ticket failure.
868 * The code of the Exception will be one of:
869 * PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE
870 * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE
871 * PHPCAS_SERVICE_PT_FAILURE
873 public static function initializeProxiedService (CAS_ProxiedService $proxiedService)
875 if (!is_object(self::$_PHPCAS_CLIENT)) {
876 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
878 if (!self::$_PHPCAS_CLIENT->isProxy()) {
879 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
881 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
882 phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
884 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
885 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
888 self::$_PHPCAS_CLIENT->initializeProxiedService($proxiedService);
892 * This method is used to access an HTTP[S] service.
894 * @param string $url the service to access.
895 * @param string &$err_code an error code Possible values are
896 * PHPCAS_SERVICE_OK (on success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE,
897 * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, PHPCAS_SERVICE_PT_FAILURE,
898 * PHPCAS_SERVICE_NOT_AVAILABLE.
899 * @param string &$output the output of the service (also used to give an
900 * error message on failure).
902 * @return bool true on success, false otherwise (in this later case,
903 * $err_code gives the reason why it failed and $output contains an error
906 public static function serviceWeb($url, & $err_code, & $output)
908 phpCAS :: traceBegin();
909 if (!is_object(self::$_PHPCAS_CLIENT)) {
910 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
912 if (!self::$_PHPCAS_CLIENT->isProxy()) {
913 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
915 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
916 phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
918 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
919 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
921 if (gettype($url) != 'string') {
922 phpCAS :: error('type mismatched for parameter $url (should be `string\')');
925 $res = self::$_PHPCAS_CLIENT->serviceWeb($url, $err_code, $output);
927 phpCAS :: traceEnd($res);
932 * This method is used to access an IMAP/POP3/NNTP service.
934 * @param string $url a string giving the URL of the service,
935 * including the mailing box for IMAP URLs, as accepted by imap_open().
936 * @param string $service a string giving for CAS retrieve Proxy ticket
937 * @param string $flags options given to imap_open().
938 * @param string &$err_code an error code Possible values are
939 * PHPCAS_SERVICE_OK (on success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE,
940 * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, PHPCAS_SERVICE_PT_FAILURE,
941 * PHPCAS_SERVICE_NOT_AVAILABLE.
942 * @param string &$err_msg an error message on failure
943 * @param string &$pt the Proxy Ticket (PT) retrieved from the CAS
944 * server to access the URL on success, false on error).
946 * @return object IMAP stream on success, false otherwise (in this later
947 * case, $err_code gives the reason why it failed and $err_msg contains an
950 public static function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt)
952 phpCAS :: traceBegin();
953 if (!is_object(self::$_PHPCAS_CLIENT)) {
954 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
956 if (!self::$_PHPCAS_CLIENT->isProxy()) {
957 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
959 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
960 phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()');
962 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
963 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
965 if (gettype($url) != 'string') {
966 phpCAS :: error('type mismatched for parameter $url (should be `string\')');
969 if (gettype($flags) != 'integer') {
970 phpCAS :: error('type mismatched for parameter $flags (should be `integer\')');
973 $res = self::$_PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt);
975 phpCAS :: traceEnd($res);
980 // ########################################################################
982 // ########################################################################
984 * @addtogroup publicAuth
989 * Set the times authentication will be cached before really accessing the
990 * CAS server in gateway mode:
991 * - -1: check only once, and then never again (until you pree login)
993 * - n: check every "n" time
995 * @param int $n an integer.
999 public static function setCacheTimesForAuthRecheck($n)
1001 if (!is_object(self::$_PHPCAS_CLIENT)) {
1002 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1004 if (gettype($n) != 'integer') {
1005 phpCAS :: error('type mismatched for parameter $n (should be `integer\')');
1007 self::$_PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);
1011 * Set a callback function to be run when a user authenticates.
1013 * The callback function will be passed a $logoutTicket as its first
1014 * parameter, followed by any $additionalArgs you pass. The $logoutTicket
1015 * parameter is an opaque string that can be used to map the session-id to
1016 * logout request in order to support single-signout in applications that
1017 * manage their own sessions (rather than letting phpCAS start the session).
1019 * phpCAS::forceAuthentication() will always exit and forward client unless
1020 * they are already authenticated. To perform an action at the moment the user
1021 * logs in (such as registering an account, performing logging, etc), register
1022 * a callback function here.
1024 * @param string $function Callback function
1025 * @param array $additionalArgs optional array of arguments
1029 public static function setPostAuthenticateCallback ($function, array $additionalArgs = array())
1031 if (!is_object(self::$_PHPCAS_CLIENT)) {
1032 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1035 self::$_PHPCAS_CLIENT->setPostAuthenticateCallback($function, $additionalArgs);
1039 * Set a callback function to be run when a single-signout request is
1040 * received. The callback function will be passed a $logoutTicket as its
1041 * first parameter, followed by any $additionalArgs you pass. The
1042 * $logoutTicket parameter is an opaque string that can be used to map a
1043 * session-id to the logout request in order to support single-signout in
1044 * applications that manage their own sessions (rather than letting phpCAS
1045 * start and destroy the session).
1047 * @param string $function Callback function
1048 * @param array $additionalArgs optional array of arguments
1052 public static function setSingleSignoutCallback ($function, array $additionalArgs = array())
1054 if (!is_object(self::$_PHPCAS_CLIENT)) {
1055 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1058 self::$_PHPCAS_CLIENT->setSingleSignoutCallback($function, $additionalArgs);
1062 * This method is called to check if the user is already authenticated
1063 * locally or has a global cas session. A already existing cas session is
1064 * determined by a cas gateway call.(cas login call without any interactive
1067 * @return true when the user is authenticated, false when a previous
1068 * gateway login failed or the function will not return if the user is
1069 * redirected to the cas server for a gateway login attempt
1071 public static function checkAuthentication()
1073 phpCAS :: traceBegin();
1074 if (!is_object(self::$_PHPCAS_CLIENT)) {
1075 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1078 $auth = self::$_PHPCAS_CLIENT->checkAuthentication();
1080 // store where the authentication has been checked and the result
1081 self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1083 phpCAS :: traceEnd($auth);
1088 * This method is called to force authentication if the user was not already
1089 * authenticated. If the user is not authenticated, halt by redirecting to
1092 * @return bool Authentication
1094 public static function forceAuthentication()
1096 phpCAS :: traceBegin();
1097 if (!is_object(self::$_PHPCAS_CLIENT)) {
1098 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1101 $auth = self::$_PHPCAS_CLIENT->forceAuthentication();
1103 // store where the authentication has been checked and the result
1104 self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1107 phpCAS :: trace('user is not authenticated, redirecting to the CAS server');
1108 self::$_PHPCAS_CLIENT->forceAuthentication();
1110 phpCAS :: trace('no need to authenticate (user `' . phpCAS :: getUser() . '\' is already authenticated)');
1113 phpCAS :: traceEnd();
1118 * This method is called to renew the authentication.
1122 public static function renewAuthentication()
1124 phpCAS :: traceBegin();
1125 if (!is_object(self::$_PHPCAS_CLIENT)) {
1126 phpCAS :: error('this method should not be called before' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1128 $auth = self::$_PHPCAS_CLIENT->renewAuthentication();
1130 // store where the authentication has been checked and the result
1131 self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1133 //self::$_PHPCAS_CLIENT->renewAuthentication();
1134 phpCAS :: traceEnd();
1138 * This method is called to check if the user is authenticated (previously or by
1139 * tickets given in the URL).
1141 * @return true when the user is authenticated.
1143 public static function isAuthenticated()
1145 phpCAS :: traceBegin();
1146 if (!is_object(self::$_PHPCAS_CLIENT)) {
1147 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1150 // call the isAuthenticated method of the $_PHPCAS_CLIENT object
1151 $auth = self::$_PHPCAS_CLIENT->isAuthenticated();
1153 // store where the authentication has been checked and the result
1154 self::$_PHPCAS_CLIENT->markAuthenticationCall($auth);
1156 phpCAS :: traceEnd($auth);
1161 * Checks whether authenticated based on $_SESSION. Useful to avoid
1164 * @return bool true if authenticated, false otherwise.
1165 * @since 0.4.22 by Brendan Arnold
1167 public static function isSessionAuthenticated()
1169 if (!is_object(self::$_PHPCAS_CLIENT)) {
1170 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1172 return (self::$_PHPCAS_CLIENT->isSessionAuthenticated());
1176 * This method returns the CAS user's login name.
1178 * @return string the login name of the authenticated user
1179 * @warning should not be called only after phpCAS::forceAuthentication()
1180 * or phpCAS::checkAuthentication().
1182 public static function getUser()
1184 if (!is_object(self::$_PHPCAS_CLIENT)) {
1185 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1187 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
1188 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
1190 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
1191 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
1193 return self::$_PHPCAS_CLIENT->getUser();
1197 * Answer attributes about the authenticated user.
1199 * @warning should not be called only after phpCAS::forceAuthentication()
1200 * or phpCAS::checkAuthentication().
1204 public static function getAttributes()
1206 if (!is_object(self::$_PHPCAS_CLIENT)) {
1207 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1209 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
1210 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
1212 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
1213 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
1215 return self::$_PHPCAS_CLIENT->getAttributes();
1219 * Answer true if there are attributes for the authenticated user.
1221 * @warning should not be called only after phpCAS::forceAuthentication()
1222 * or phpCAS::checkAuthentication().
1226 public static function hasAttributes()
1228 if (!is_object(self::$_PHPCAS_CLIENT)) {
1229 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1231 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
1232 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
1234 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
1235 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
1237 return self::$_PHPCAS_CLIENT->hasAttributes();
1241 * Answer true if an attribute exists for the authenticated user.
1243 * @param string $key attribute name
1246 * @warning should not be called only after phpCAS::forceAuthentication()
1247 * or phpCAS::checkAuthentication().
1249 public static function hasAttribute($key)
1251 if (!is_object(self::$_PHPCAS_CLIENT)) {
1252 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1254 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
1255 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
1257 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
1258 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
1260 return self::$_PHPCAS_CLIENT->hasAttribute($key);
1264 * Answer an attribute for the authenticated user.
1266 * @param string $key attribute name
1268 * @return mixed string for a single value or an array if multiple values exist.
1269 * @warning should not be called only after phpCAS::forceAuthentication()
1270 * or phpCAS::checkAuthentication().
1272 public static function getAttribute($key)
1274 if (!is_object(self::$_PHPCAS_CLIENT)) {
1275 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1277 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCalled()) {
1278 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
1280 if (!self::$_PHPCAS_CLIENT->wasAuthenticationCallSuccessful()) {
1281 phpCAS :: error('authentication was checked (by ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerMethod() . '() at ' . self::$_PHPCAS_CLIENT->getAuthenticationCallerFile() . ':' . self::$_PHPCAS_CLIENT->getAuthenticationCallerLine() . ') but the method returned false');
1283 return self::$_PHPCAS_CLIENT->getAttribute($key);
1287 * Handle logout requests.
1289 * @param bool $check_client additional safety check
1290 * @param array $allowed_clients array of allowed clients
1294 public static function handleLogoutRequests($check_client = true, $allowed_clients = false)
1296 if (!is_object(self::$_PHPCAS_CLIENT)) {
1297 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1299 return (self::$_PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients));
1303 * This method returns the URL to be used to login.
1304 * or phpCAS::isAuthenticated().
1306 * @return the login name of the authenticated user
1308 public static function getServerLoginURL()
1310 if (!is_object(self::$_PHPCAS_CLIENT)) {
1311 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1313 return self::$_PHPCAS_CLIENT->getServerLoginURL();
1317 * Set the login URL of the CAS server.
1319 * @param string $url the login URL
1322 * @since 0.4.21 by Wyman Chan
1324 public static function setServerLoginURL($url = '')
1326 phpCAS :: traceBegin();
1327 if (!is_object(self::$_PHPCAS_CLIENT)) {
1328 phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
1330 if (gettype($url) != 'string') {
1331 phpCAS :: error('type mismatched for parameter $url (should be `string`)');
1333 self::$_PHPCAS_CLIENT->setServerLoginURL($url);
1334 phpCAS :: traceEnd();
1338 * Set the serviceValidate URL of the CAS server.
1339 * Used only in CAS 1.0 validations
1341 * @param string $url the serviceValidate URL
1345 public static function setServerServiceValidateURL($url = '')
1347 phpCAS :: traceBegin();
1348 if (!is_object(self::$_PHPCAS_CLIENT)) {
1349 phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
1351 if (gettype($url) != 'string') {
1352 phpCAS :: error('type mismatched for parameter $url (should be `string`)');
1354 self::$_PHPCAS_CLIENT->setServerServiceValidateURL($url);
1355 phpCAS :: traceEnd();
1359 * Set the proxyValidate URL of the CAS server.
1360 * Used for all CAS 2.0 validations
1362 * @param string $url the proxyValidate URL
1366 public static function setServerProxyValidateURL($url = '')
1368 phpCAS :: traceBegin();
1369 if (!is_object(self::$_PHPCAS_CLIENT)) {
1370 phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
1372 if (gettype($url) != 'string') {
1373 phpCAS :: error('type mismatched for parameter $url (should be `string`)');
1375 self::$_PHPCAS_CLIENT->setServerProxyValidateURL($url);
1376 phpCAS :: traceEnd();
1380 * Set the samlValidate URL of the CAS server.
1382 * @param string $url the samlValidate URL
1386 public static function setServerSamlValidateURL($url = '')
1388 phpCAS :: traceBegin();
1389 if (!is_object(self::$_PHPCAS_CLIENT)) {
1390 phpCAS :: error('this method should only be called after' . __CLASS__ . '::client()');
1392 if (gettype($url) != 'string') {
1393 phpCAS :: error('type mismatched for parameter $url (should be`string\')');
1395 self::$_PHPCAS_CLIENT->setServerSamlValidateURL($url);
1396 phpCAS :: traceEnd();
1400 * This method returns the URL to be used to login.
1401 * or phpCAS::isAuthenticated().
1403 * @return the login name of the authenticated user
1405 public static function getServerLogoutURL()
1407 if (!is_object(self::$_PHPCAS_CLIENT)) {
1408 phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1410 return self::$_PHPCAS_CLIENT->getServerLogoutURL();
1414 * Set the logout URL of the CAS server.
1416 * @param string $url the logout URL
1419 * @since 0.4.21 by Wyman Chan
1421 public static function setServerLogoutURL($url = '')
1423 phpCAS :: traceBegin();
1424 if (!is_object(self::$_PHPCAS_CLIENT)) {
1426 'this method should only be called after' . __CLASS__ . '::client()'
1429 if (gettype($url) != 'string') {
1431 'type mismatched for parameter $url (should be `string`)'
1434 self::$_PHPCAS_CLIENT->setServerLogoutURL($url);
1435 phpCAS :: traceEnd();
1439 * This method is used to logout from CAS.
1441 * @param string $params an array that contains the optional url and
1442 * service parameters that will be passed to the CAS server
1446 public static function logout($params = "")
1448 phpCAS :: traceBegin();
1449 if (!is_object(self::$_PHPCAS_CLIENT)) {
1450 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1452 $parsedParams = array ();
1453 if ($params != "") {
1454 if (is_string($params)) {
1455 phpCAS :: error('method `phpCAS::logout($url)\' is now deprecated, use `phpCAS::logoutWithUrl($url)\' instead');
1457 if (!is_array($params)) {
1458 phpCAS :: error('type mismatched for parameter $params (should be `array\')');
1460 foreach ($params as $key => $value) {
1461 if ($key != "service" && $key != "url") {
1462 phpCAS :: error('only `url\' and `service\' parameters are allowed for method `phpCAS::logout($params)\'');
1464 $parsedParams[$key] = $value;
1467 self::$_PHPCAS_CLIENT->logout($parsedParams);
1469 phpCAS :: traceEnd();
1473 * This method is used to logout from CAS. Halts by redirecting to the CAS
1476 * @param service $service a URL that will be transmitted to the CAS server
1480 public static function logoutWithRedirectService($service)
1482 phpCAS :: traceBegin();
1483 if (!is_object(self::$_PHPCAS_CLIENT)) {
1484 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1486 if (!is_string($service)) {
1487 phpCAS :: error('type mismatched for parameter $service (should be `string\')');
1489 self::$_PHPCAS_CLIENT->logout(array ( "service" => $service ));
1491 phpCAS :: traceEnd();
1495 * This method is used to logout from CAS. Halts by redirecting to the CAS
1498 * @param string $url a URL that will be transmitted to the CAS server
1501 * @deprecated The url parameter has been removed from the CAS server as of
1504 public static function logoutWithUrl($url)
1506 trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED);
1507 phpCAS :: traceBegin();
1508 if (!is_object(self::$_PHPCAS_CLIENT)) {
1509 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1511 if (!is_string($url)) {
1512 phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1514 self::$_PHPCAS_CLIENT->logout(array ( "url" => $url ));
1516 phpCAS :: traceEnd();
1520 * This method is used to logout from CAS. Halts by redirecting to the CAS
1523 * @param string $service a URL that will be transmitted to the CAS server
1524 * @param string $url a URL that will be transmitted to the CAS server
1528 * @deprecated The url parameter has been removed from the CAS server as of
1531 public static function logoutWithRedirectServiceAndUrl($service, $url)
1533 trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED);
1534 phpCAS :: traceBegin();
1535 if (!is_object(self::$_PHPCAS_CLIENT)) {
1536 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1538 if (!is_string($service)) {
1539 phpCAS :: error('type mismatched for parameter $service (should be `string\')');
1541 if (!is_string($url)) {
1542 phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1544 self::$_PHPCAS_CLIENT->logout(
1546 "service" => $service,
1551 phpCAS :: traceEnd();
1555 * Set the fixed URL that will be used by the CAS server to transmit the
1556 * PGT. When this method is not called, a phpCAS script uses its own URL
1559 * @param string $url the URL
1563 public static function setFixedCallbackURL($url = '')
1565 phpCAS :: traceBegin();
1566 if (!is_object(self::$_PHPCAS_CLIENT)) {
1567 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1569 if (!self::$_PHPCAS_CLIENT->isProxy()) {
1570 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1572 if (gettype($url) != 'string') {
1573 phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1575 self::$_PHPCAS_CLIENT->setCallbackURL($url);
1576 phpCAS :: traceEnd();
1580 * Set the fixed URL that will be set as the CAS service parameter. When this
1581 * method is not called, a phpCAS script uses its own URL.
1583 * @param string $url the URL
1587 public static function setFixedServiceURL($url)
1589 phpCAS :: traceBegin();
1590 if (!is_object(self::$_PHPCAS_CLIENT)) {
1591 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1593 if (gettype($url) != 'string') {
1594 phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1596 self::$_PHPCAS_CLIENT->setURL($url);
1597 phpCAS :: traceEnd();
1601 * Get the URL that is set as the CAS service parameter.
1603 * @return string Service Url
1605 public static function getServiceURL()
1607 if (!is_object(self::$_PHPCAS_CLIENT)) {
1608 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1610 return (self::$_PHPCAS_CLIENT->getURL());
1614 * Retrieve a Proxy Ticket from the CAS server.
1616 * @param string $target_service Url string of service to proxy
1617 * @param string &$err_code error code
1618 * @param string &$err_msg error message
1620 * @return string Proxy Ticket
1622 public static function retrievePT($target_service, & $err_code, & $err_msg)
1624 if (!is_object(self::$_PHPCAS_CLIENT)) {
1625 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1627 if (gettype($target_service) != 'string') {
1628 phpCAS :: error('type mismatched for parameter $target_service(should be `string\')');
1630 return (self::$_PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg));
1634 * Set the certificate of the CAS server CA and if the CN should be properly
1637 * @param string $cert CA certificate file name
1638 * @param bool $validate_cn Validate CN in certificate (default true)
1642 public static function setCasServerCACert($cert, $validate_cn = true)
1644 phpCAS :: traceBegin();
1645 if (!is_object(self::$_PHPCAS_CLIENT)) {
1646 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1648 if (gettype($cert) != 'string') {
1649 phpCAS :: error('type mismatched for parameter $cert (should be `string\')');
1651 if (gettype($validate_cn) != 'boolean') {
\r
1652 phpCAS :: error('type mismatched for parameter $validate_cn (should be `boolean\')');
\r
1654 self::$_PHPCAS_CLIENT->setCasServerCACert($cert, $validate_cn);
1655 phpCAS :: traceEnd();
1659 * Set no SSL validation for the CAS server.
1663 public static function setNoCasServerValidation()
1665 phpCAS :: traceBegin();
1666 if (!is_object(self::$_PHPCAS_CLIENT)) {
1667 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1669 phpCAS :: trace('You have configured no validation of the legitimacy of the cas server. This is not recommended for production use.');
1670 self::$_PHPCAS_CLIENT->setNoCasServerValidation();
1671 phpCAS :: traceEnd();
1676 * Disable the removal of a CAS-Ticket from the URL when authenticating
1677 * DISABLING POSES A SECURITY RISK:
1678 * We normally remove the ticket by an additional redirect as a security
1679 * precaution to prevent a ticket in the HTTP_REFERRER or be carried over in
1684 public static function setNoClearTicketsFromUrl()
1686 phpCAS :: traceBegin();
1687 if (!is_object(self::$_PHPCAS_CLIENT)) {
1688 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1690 self::$_PHPCAS_CLIENT->setNoClearTicketsFromUrl();
1691 phpCAS :: traceEnd();
1697 * Change CURL options.
1698 * CURL is used to connect through HTTPS to CAS server
1700 * @param string $key the option key
1701 * @param string $value the value to set
1705 public static function setExtraCurlOption($key, $value)
1707 phpCAS :: traceBegin();
1708 if (!is_object(self::$_PHPCAS_CLIENT)) {
1709 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1711 self::$_PHPCAS_CLIENT->setExtraCurlOption($key, $value);
1712 phpCAS :: traceEnd();
1716 * If you want your service to be proxied you have to enable it (default
1717 * disabled) and define an accepable list of proxies that are allowed to
1718 * proxy your service.
1720 * Add each allowed proxy definition object. For the normal CAS_ProxyChain
1721 * class, the constructor takes an array of proxies to match. The list is in
1722 * reverse just as seen from the service. Proxies have to be defined in reverse
1723 * from the service to the user. If a user hits service A and gets proxied via
1724 * B to service C the list of acceptable on C would be array(B,A). The definition
1725 * of an individual proxy can be either a string or a regexp (preg_match is used)
1726 * that will be matched against the proxy list supplied by the cas server
1727 * when validating the proxy tickets. The strings are compared starting from
1728 * the beginning and must fully match with the proxies in the list.
1730 * phpCAS::allowProxyChain(new CAS_ProxyChain(array(
1731 * 'https://app.example.com/'
1733 * phpCAS::allowProxyChain(new CAS_ProxyChain(array(
1734 * '/^https:\/\/app[0-9]\.example\.com\/rest\//',
1735 * 'http://client.example.com/'
1738 * For quick testing or in certain production screnarios you might want to
1739 * allow allow any other valid service to proxy your service. To do so, add
1741 * phpcas::allowProxyChain(new CAS_ProxyChain_Any);
1742 * THIS SETTING IS HOWEVER NOT RECOMMENDED FOR PRODUCTION AND HAS SECURITY
1743 * IMPLICATIONS: YOU ARE ALLOWING ANY SERVICE TO ACT ON BEHALF OF A USER
1746 * @param CAS_ProxyChain_Interface $proxy_chain A proxy-chain that will be
1747 * matched against the proxies requesting access
1751 public static function allowProxyChain(CAS_ProxyChain_Interface $proxy_chain)
1753 phpCAS :: traceBegin();
1754 if (!is_object(self::$_PHPCAS_CLIENT)) {
1755 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1757 if (self::$_PHPCAS_CLIENT->getServerVersion() !== CAS_VERSION_2_0) {
1758 phpCAS :: error('this method can only be used with the cas 2.0 protool');
1760 self::$_PHPCAS_CLIENT->getAllowedProxyChains()->allowProxyChain($proxy_chain);
1761 phpCAS :: traceEnd();
1765 * Answer an array of proxies that are sitting in front of this application.
1766 * This method will only return a non-empty array if we have received and
1767 * validated a Proxy Ticket.
1773 public static function getProxies ()
1775 if ( !is_object(self::$_PHPCAS_CLIENT) ) {
1776 phpCAS::error('this method should only be called after '.__CLASS__.'::client()');
1779 return(self::$_PHPCAS_CLIENT->getProxies());
1782 // ########################################################################
1783 // PGTIOU/PGTID and logoutRequest rebroadcasting
1784 // ########################################################################
1787 * Add a pgtIou/pgtId and logoutRequest rebroadcast node.
1789 * @param string $rebroadcastNodeUrl The rebroadcast node URL. Can be
1794 public static function addRebroadcastNode($rebroadcastNodeUrl)
1796 phpCAS::traceBegin();
1797 phpCAS::log('rebroadcastNodeUrl:'.$rebroadcastNodeUrl);
1798 if (!is_object(self::$_PHPCAS_CLIENT)) {
1799 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1801 if ( !(bool)preg_match("/^(http|https):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i", $rebroadcastNodeUrl)) {
1802 phpCAS::error('type mismatched for parameter $rebroadcastNodeUrl (should be `url\')');
1804 self::$_PHPCAS_CLIENT->addRebroadcastNode($rebroadcastNodeUrl);
1809 * This method is used to add header parameters when rebroadcasting
1810 * pgtIou/pgtId or logoutRequest.
1812 * @param String $header Header to send when rebroadcasting.
1816 public static function addRebroadcastHeader($header)
1818 phpCAS :: traceBegin();
1819 if (!is_object(self::$_PHPCAS_CLIENT)) {
1820 phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1822 self::$_PHPCAS_CLIENT->addRebroadcastHeader($header);
1823 phpCAS :: traceEnd();
1827 // ########################################################################
1829 // ########################################################################
1831 // ########################################################################
1837 * The following pages only show the source documentation.
1841 // ########################################################################
1842 // MODULES DEFINITION
1844 /** @defgroup public User interface */
1846 /** @defgroup publicInit Initialization
1847 * @ingroup public */
1849 /** @defgroup publicAuth Authentication
1850 * @ingroup public */
1852 /** @defgroup publicServices Access to external services
1853 * @ingroup public */
1855 /** @defgroup publicConfig Configuration
1856 * @ingroup public */
1858 /** @defgroup publicLang Internationalization
1859 * @ingroup publicConfig */
1861 /** @defgroup publicOutput HTML output
1862 * @ingroup publicConfig */
1864 /** @defgroup publicPGTStorage PGT storage
1865 * @ingroup publicConfig */
1867 /** @defgroup publicDebug Debugging
1868 * @ingroup public */
1870 /** @defgroup internal Implementation */
1872 /** @defgroup internalAuthentication Authentication
1873 * @ingroup internal */
1875 /** @defgroup internalBasic CAS Basic client features (CAS 1.0, Service Tickets)
1876 * @ingroup internal */
1878 /** @defgroup internalProxy CAS Proxy features (CAS 2.0, Proxy Granting Tickets)
1879 * @ingroup internal */
1881 /** @defgroup internalSAML CAS SAML features (SAML 1.1)
1882 * @ingroup internal */
1884 /** @defgroup internalPGTStorage PGT storage
1885 * @ingroup internalProxy */
1887 /** @defgroup internalPGTStorageDb PGT storage in a database
1888 * @ingroup internalPGTStorage */
1890 /** @defgroup internalPGTStorageFile PGT storage on the filesystem
1891 * @ingroup internalPGTStorage */
1893 /** @defgroup internalCallback Callback from the CAS server
1894 * @ingroup internalProxy */
1896 /** @defgroup internalProxyServices Proxy other services
1897 * @ingroup internalProxy */
1899 /** @defgroup internalService CAS client features (CAS 2.0, Proxied service)
1900 * @ingroup internal */
1902 /** @defgroup internalConfig Configuration
1903 * @ingroup internal */
1905 /** @defgroup internalBehave Internal behaviour of phpCAS
1906 * @ingroup internalConfig */
1908 /** @defgroup internalOutput HTML output
1909 * @ingroup internalConfig */
1911 /** @defgroup internalLang Internationalization
1912 * @ingroup internalConfig
1914 * To add a new language:
1915 * - 1. define a new constant PHPCAS_LANG_XXXXXX in CAS/CAS.php
1916 * - 2. copy any file from CAS/languages to CAS/languages/XXXXXX.php
1917 * - 3. Make the translations
1920 /** @defgroup internalDebug Debugging
1921 * @ingroup internal */
1923 /** @defgroup internalMisc Miscellaneous
1924 * @ingroup internal */
1926 // ########################################################################
1930 * @example example_simple.php
1933 * @example example_service.php
1936 * @example example_service_that_proxies.php
1939 * @example example_service_POST.php
1942 * @example example_proxy_serviceWeb.php
1945 * @example example_proxy_serviceWeb_chaining.php
1948 * @example example_proxy_POST.php
1951 * @example example_proxy_GET.php
1954 * @example example_lang.php
1957 * @example example_html.php
1960 * @example example_pgt_storage_file.php
1963 * @example example_pgt_storage_db.php
1966 * @example example_gateway.php
1969 * @example example_logout.php
1972 * @example example_rebroadcast.php
1975 * @example example_custom_urls.php
1978 * @example example_advanced_saml11.php