4
* Copyright © 2003-2010, The ESUP-Portail consortium & the JA-SIG Collaborative.
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are met:
10
* * Redistributions of source code must retain the above copyright notice,
11
* this list of conditions and the following disclaimer.
12
* * Redistributions in binary form must reproduce the above copyright notice,
13
* this list of conditions and the following disclaimer in the documentation
14
* and/or other materials provided with the distribution.
15
* * Neither the name of the ESUP-Portail consortium & the JA-SIG
16
* Collaborative nor the names of its contributors may be used to endorse or
17
* promote products derived from this software without specific prior
20
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
24
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
// hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI'] in IIS
35
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'];
36
if (isset($_SERVER['QUERY_STRING'])) {
37
$_SERVER['REQUEST_URI'] .= '?' . $_SERVER['QUERY_STRING'];
41
// another one by Vangelis Haniotakis also to make phpCAS work with PHP5
43
if (version_compare(PHP_VERSION, '5', '>=') && !(function_exists('domxml_new_doc'))) {
44
require_once (dirname(__FILE__) . '/CAS/domxml-php4-to-php5.php');
49
* Interface class of the phpCAS library
54
// ########################################################################
56
// ########################################################################
58
// ------------------------------------------------------------------------
60
// ------------------------------------------------------------------------
63
* phpCAS version. accessible for the user by phpCAS::getVersion().
65
define('PHPCAS_VERSION', '1.1.3');
67
// ------------------------------------------------------------------------
69
// ------------------------------------------------------------------------
78
define("CAS_VERSION_1_0", '1.0');
82
define("CAS_VERSION_2_0", '2.0');
84
// ------------------------------------------------------------------------
86
// ------------------------------------------------------------------------
91
define("SAML_VERSION_1_1", 'S1');
94
* XML header for SAML POST
96
define("SAML_XML_HEADER", '<?xml version="1.0" encoding="UTF-8"?>');
99
* SOAP envelope for SAML POST
101
define("SAML_SOAP_ENV", '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/>');
104
* SOAP body for SAML POST
106
define("SAML_SOAP_BODY", '<SOAP-ENV:Body>');
111
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">');
112
define("SAMLP_REQUEST_CLOSE", '</samlp:Request>');
115
* SAMLP artifact tag (for the ticket)
117
define("SAML_ASSERTION_ARTIFACT", '<samlp:AssertionArtifact>');
122
define("SAML_ASSERTION_ARTIFACT_CLOSE", '</samlp:AssertionArtifact>');
127
define("SAML_SOAP_BODY_CLOSE", '</SOAP-ENV:Body>');
130
* SOAP envelope close
132
define("SAML_SOAP_ENV_CLOSE", '</SOAP-ENV:Envelope>');
137
define("SAML_ATTRIBUTES", 'SAMLATTRIBS');
141
* @addtogroup publicPGTStorage
144
// ------------------------------------------------------------------------
146
// ------------------------------------------------------------------------
148
* Default path used when storing PGT's to file
150
define("CAS_PGT_STORAGE_FILE_DEFAULT_PATH", '/tmp');
152
* phpCAS::setPGTStorageFile()'s 2nd parameter to write plain text files
154
define("CAS_PGT_STORAGE_FILE_FORMAT_PLAIN", 'plain');
156
* phpCAS::setPGTStorageFile()'s 2nd parameter to write xml files
158
define("CAS_PGT_STORAGE_FILE_FORMAT_XML", 'xml');
160
* Default format used when storing PGT's to file
162
define("CAS_PGT_STORAGE_FILE_DEFAULT_FORMAT", CAS_PGT_STORAGE_FILE_FORMAT_PLAIN);
164
// ------------------------------------------------------------------------
165
// SERVICE ACCESS ERRORS
166
// ------------------------------------------------------------------------
168
* @addtogroup publicServices
173
* phpCAS::service() error code on success
175
define("PHPCAS_SERVICE_OK", 0);
177
* phpCAS::service() error code when the PT could not retrieve because
178
* the CAS server did not respond.
180
define("PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE", 1);
182
* phpCAS::service() error code when the PT could not retrieve because
183
* the response of the CAS server was ill-formed.
185
define("PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE", 2);
187
* phpCAS::service() error code when the PT could not retrieve because
188
* the CAS server did not want to.
190
define("PHPCAS_SERVICE_PT_FAILURE", 3);
192
* phpCAS::service() error code when the service was not available.
194
define("PHPCAS_SERVICE_NOT AVAILABLE", 4);
197
// ------------------------------------------------------------------------
199
// ------------------------------------------------------------------------
201
* @addtogroup publicLang
205
define("PHPCAS_LANG_ENGLISH", 'english');
206
define("PHPCAS_LANG_FRENCH", 'french');
207
define("PHPCAS_LANG_GREEK", 'greek');
208
define("PHPCAS_LANG_GERMAN", 'german');
209
define("PHPCAS_LANG_JAPANESE", 'japanese');
210
define("PHPCAS_LANG_SPANISH", 'spanish');
211
define("PHPCAS_LANG_CATALAN", 'catalan');
216
* @addtogroup internalLang
221
* phpCAS default language (when phpCAS::setLang() is not used)
223
define("PHPCAS_LANG_DEFAULT", PHPCAS_LANG_ENGLISH);
226
// ------------------------------------------------------------------------
228
// ------------------------------------------------------------------------
230
* @addtogroup publicDebug
235
* The default directory for the debug file under Unix.
237
define('DEFAULT_DEBUG_DIR', '/tmp/');
240
// ------------------------------------------------------------------------
242
// ------------------------------------------------------------------------
244
* @addtogroup internalMisc
249
* This global variable is used by the interface class phpCAS.
253
$GLOBALS['PHPCAS_CLIENT'] = null;
256
* This global variable is used to store where the initializer is called from
257
* (to print a comprehensive error in case of multiple calls).
261
$GLOBALS['PHPCAS_INIT_CALL'] = array (
269
* This global variable is used to store where the method checking
270
* the authentication is called from (to print comprehensive errors)
274
$GLOBALS['PHPCAS_AUTH_CHECK_CALL'] = array (
283
* This global variable is used to store phpCAS debug mode.
287
$GLOBALS['PHPCAS_DEBUG'] = array (
295
// ########################################################################
297
// ########################################################################
299
// include client class
300
include_once (dirname(__FILE__) . '/CAS/client.php');
302
// ########################################################################
304
// ########################################################################
308
* The phpCAS class is a simple container for the phpCAS library. It provides CAS
309
* authentication for web applications written in PHP.
312
* @author Pascal Aubry <pascal.aubry at univ-rennes1.fr>
314
* \internal All its methods access the same object ($PHPCAS_CLIENT, declared
315
* at the end of CAS/client.php).
320
// ########################################################################
322
// ########################################################################
325
* @addtogroup publicInit
330
* phpCAS client initializer.
331
* @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
332
* called, only once, and before all other methods (except phpCAS::getVersion()
333
* and phpCAS::setDebug()).
335
* @param $server_version the version of the CAS server
336
* @param $server_hostname the hostname of the CAS server
337
* @param $server_port the port the CAS server is running on
338
* @param $server_uri the URI the CAS server is responding on
339
* @param $start_session Have phpCAS start PHP sessions (default true)
341
* @return a newly created CASClient object
343
public static function client($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) {
344
global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL;
346
phpCAS :: traceBegin();
347
if (is_object($PHPCAS_CLIENT)) {
348
phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')');
350
if (gettype($server_version) != 'string') {
351
phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');
353
if (gettype($server_hostname) != 'string') {
354
phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');
356
if (gettype($server_port) != 'integer') {
357
phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');
359
if (gettype($server_uri) != 'string') {
360
phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');
363
// store where the initializer is called from
364
$dbg = phpCAS :: backtrace();
365
$PHPCAS_INIT_CALL = array (
367
'file' => $dbg[0]['file'],
368
'line' => $dbg[0]['line'],
369
'method' => __CLASS__ . '::' . __FUNCTION__
372
// initialize the global object $PHPCAS_CLIENT
373
$PHPCAS_CLIENT = new CASClient($server_version, FALSE /*proxy*/
374
, $server_hostname, $server_port, $server_uri, $start_session);
375
phpCAS :: traceEnd();
379
* phpCAS proxy initializer.
380
* @note Only one of the phpCAS::client() and phpCAS::proxy functions should be
381
* called, only once, and before all other methods (except phpCAS::getVersion()
382
* and phpCAS::setDebug()).
384
* @param $server_version the version of the CAS server
385
* @param $server_hostname the hostname of the CAS server
386
* @param $server_port the port the CAS server is running on
387
* @param $server_uri the URI the CAS server is responding on
388
* @param $start_session Have phpCAS start PHP sessions (default true)
390
* @return a newly created CASClient object
392
public static function proxy($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) {
393
global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL;
395
phpCAS :: traceBegin();
396
if (is_object($PHPCAS_CLIENT)) {
397
phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')');
399
if (gettype($server_version) != 'string') {
400
phpCAS :: error('type mismatched for parameter $server_version (should be `string\')');
402
if (gettype($server_hostname) != 'string') {
403
phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')');
405
if (gettype($server_port) != 'integer') {
406
phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')');
408
if (gettype($server_uri) != 'string') {
409
phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')');
412
// store where the initialzer is called from
413
$dbg = phpCAS :: backtrace();
414
$PHPCAS_INIT_CALL = array (
416
'file' => $dbg[0]['file'],
417
'line' => $dbg[0]['line'],
418
'method' => __CLASS__ . '::' . __FUNCTION__
421
// initialize the global object $PHPCAS_CLIENT
422
$PHPCAS_CLIENT = new CASClient($server_version, TRUE /*proxy*/
423
, $server_hostname, $server_port, $server_uri, $start_session);
424
phpCAS :: traceEnd();
428
// ########################################################################
430
// ########################################################################
433
* @addtogroup publicDebug
438
* Set/unset debug mode
440
* @param $filename the name of the file used for logging, or FALSE to stop debugging.
442
public static function setDebug($filename = '') {
443
global $PHPCAS_DEBUG;
445
if ($filename != FALSE && gettype($filename) != 'string') {
446
phpCAS :: error('type mismatched for parameter $dbg (should be FALSE or the name of the log file)');
449
if (empty ($filename)) {
450
if (preg_match('/^Win.*/', getenv('OS'))) {
451
if (isset ($_ENV['TMP'])) {
452
$debugDir = $_ENV['TMP'] . '/';
454
if (isset ($_ENV['TEMP'])) {
455
$debugDir = $_ENV['TEMP'] . '/';
460
$debugDir = DEFAULT_DEBUG_DIR;
462
$filename = $debugDir . 'phpCAS.log';
465
if (empty ($PHPCAS_DEBUG['unique_id'])) {
466
$PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4);
469
$PHPCAS_DEBUG['filename'] = $filename;
471
phpCAS :: trace('START phpCAS-' . PHPCAS_VERSION . ' ******************');
476
* @addtogroup internalDebug
481
* This method is a wrapper for debug_backtrace() that is not available
482
* in all PHP versions (>= 4.3.0 only)
484
public static function backtrace() {
485
if (function_exists('debug_backtrace')) {
486
return debug_backtrace();
488
// poor man's hack ... but it does work ...
494
* Logs a string in debug mode.
496
* @param $str the string to write
500
public static function log($str) {
502
global $PHPCAS_DEBUG;
504
if ($PHPCAS_DEBUG['filename']) {
505
for ($i = 0; $i < $PHPCAS_DEBUG['indent']; $i++) {
508
error_log($PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str . "\n", 3, $PHPCAS_DEBUG['filename']);
514
* This method is used by interface methods to print an error and where the function
515
* was originally called from.
517
* @param $msg the message to print
521
public static function error($msg) {
522
$dbg = phpCAS :: backtrace();
526
if (is_array($dbg)) {
527
for ($i = 1; $i < sizeof($dbg); $i++) {
528
if (is_array($dbg[$i])) {
529
if ($dbg[$i]['class'] == __CLASS__) {
530
$function = $dbg[$i]['function'];
531
$file = $dbg[$i]['file'];
532
$line = $dbg[$i]['line'];
537
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";
538
phpCAS :: trace($msg);
539
phpCAS :: traceExit();
544
* This method is used to log something in debug mode.
546
public static function trace($str) {
547
$dbg = phpCAS :: backtrace();
548
phpCAS :: log($str . ' [' . basename($dbg[1]['file']) . ':' . $dbg[1]['line'] . ']');
552
* This method is used to indicate the start of the execution of a function in debug mode.
554
public static function traceBegin() {
555
global $PHPCAS_DEBUG;
557
$dbg = phpCAS :: backtrace();
559
if (!empty ($dbg[2]['class'])) {
560
$str .= $dbg[2]['class'] . '::';
562
$str .= $dbg[2]['function'] . '(';
563
if (is_array($dbg[2]['args'])) {
564
foreach ($dbg[2]['args'] as $index => $arg) {
568
$str .= str_replace("\n", "", var_export($arg, TRUE));
571
$str .= ') [' . basename($dbg[2]['file']) . ':' . $dbg[2]['line'] . ']';
573
$PHPCAS_DEBUG['indent']++;
577
* This method is used to indicate the end of the execution of a function in debug mode.
579
* @param $res the result of the function
581
public static function traceEnd($res = '') {
582
global $PHPCAS_DEBUG;
584
$PHPCAS_DEBUG['indent']--;
585
$dbg = phpCAS :: backtrace();
587
$str .= '<= ' . str_replace("\n", "", var_export($res, TRUE));
592
* This method is used to indicate the end of the execution of the program
594
public static function traceExit() {
595
global $PHPCAS_DEBUG;
597
phpCAS :: log('exit()');
598
while ($PHPCAS_DEBUG['indent'] > 0) {
600
$PHPCAS_DEBUG['indent']--;
605
// ########################################################################
606
// INTERNATIONALIZATION
607
// ########################################################################
609
* @addtogroup publicLang
614
* This method is used to set the language used by phpCAS.
615
* @note Can be called only once.
617
* @param $lang a string representing the language.
619
* @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH
621
public static function setLang($lang) {
622
global $PHPCAS_CLIENT;
623
if (!is_object($PHPCAS_CLIENT)) {
624
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
626
if (gettype($lang) != 'string') {
627
phpCAS :: error('type mismatched for parameter $lang (should be `string\')');
629
$PHPCAS_CLIENT->setLang($lang);
633
// ########################################################################
635
// ########################################################################
642
* This method returns the phpCAS version.
644
* @return the phpCAS version.
646
public static function getVersion() {
647
return PHPCAS_VERSION;
651
// ########################################################################
653
// ########################################################################
655
* @addtogroup publicOutput
660
* This method sets the HTML header used for all outputs.
662
* @param $header the HTML header.
664
public static function setHTMLHeader($header) {
665
global $PHPCAS_CLIENT;
666
if (!is_object($PHPCAS_CLIENT)) {
667
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
669
if (gettype($header) != 'string') {
670
phpCAS :: error('type mismatched for parameter $header (should be `string\')');
672
$PHPCAS_CLIENT->setHTMLHeader($header);
676
* This method sets the HTML footer used for all outputs.
678
* @param $footer the HTML footer.
680
public static function setHTMLFooter($footer) {
681
global $PHPCAS_CLIENT;
682
if (!is_object($PHPCAS_CLIENT)) {
683
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
685
if (gettype($footer) != 'string') {
686
phpCAS :: error('type mismatched for parameter $footer (should be `string\')');
688
$PHPCAS_CLIENT->setHTMLFooter($footer);
692
// ########################################################################
694
// ########################################################################
696
* @addtogroup publicPGTStorage
701
* This method is used to tell phpCAS to store the response of the
702
* CAS server to PGT requests onto the filesystem.
704
* @param $format the format used to store the PGT's (`plain' and `xml' allowed)
705
* @param $path the path where the PGT's should be stored
707
public static function setPGTStorageFile($format = '', $path = '') {
708
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
710
phpCAS :: traceBegin();
711
if (!is_object($PHPCAS_CLIENT)) {
712
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
714
if (!$PHPCAS_CLIENT->isProxy()) {
715
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
717
if ($PHPCAS_AUTH_CHECK_CALL['done']) {
718
phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')');
720
if (gettype($format) != 'string') {
721
phpCAS :: error('type mismatched for parameter $format (should be `string\')');
723
if (gettype($path) != 'string') {
724
phpCAS :: error('type mismatched for parameter $format (should be `string\')');
726
$PHPCAS_CLIENT->setPGTStorageFile($format, $path);
727
phpCAS :: traceEnd();
732
// ########################################################################
733
// ACCESS TO EXTERNAL SERVICES
734
// ########################################################################
736
* @addtogroup publicServices
741
* This method is used to access an HTTP[S] service.
743
* @param $url the service to access.
744
* @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on
745
* success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,
746
* PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT AVAILABLE.
747
* @param $output the output of the service (also used to give an error
748
* message on failure).
750
* @return TRUE on success, FALSE otherwise (in this later case, $err_code
751
* gives the reason why it failed and $output contains an error message).
753
public static function serviceWeb($url, & $err_code, & $output) {
754
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
756
phpCAS :: traceBegin();
757
if (!is_object($PHPCAS_CLIENT)) {
758
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
760
if (!$PHPCAS_CLIENT->isProxy()) {
761
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
763
if (!$PHPCAS_AUTH_CHECK_CALL['done']) {
764
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()');
766
if (!$PHPCAS_AUTH_CHECK_CALL['result']) {
767
phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');
769
if (gettype($url) != 'string') {
770
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
773
$res = $PHPCAS_CLIENT->serviceWeb($url, $err_code, $output);
775
phpCAS :: traceEnd($res);
780
* This method is used to access an IMAP/POP3/NNTP service.
782
* @param $url a string giving the URL of the service, including the mailing box
783
* for IMAP URLs, as accepted by imap_open().
784
* @param $service a string giving for CAS retrieve Proxy ticket
785
* @param $flags options given to imap_open().
786
* @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on
787
* success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE,
788
* PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT AVAILABLE.
789
* @param $err_msg an error message on failure
790
* @param $pt the Proxy Ticket (PT) retrieved from the CAS server to access the URL
791
* on success, FALSE on error).
793
* @return an IMAP stream on success, FALSE otherwise (in this later case, $err_code
794
* gives the reason why it failed and $err_msg contains an error message).
796
public static function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt) {
797
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
799
phpCAS :: traceBegin();
800
if (!is_object($PHPCAS_CLIENT)) {
801
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
803
if (!$PHPCAS_CLIENT->isProxy()) {
804
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
806
if (!$PHPCAS_AUTH_CHECK_CALL['done']) {
807
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()');
809
if (!$PHPCAS_AUTH_CHECK_CALL['result']) {
810
phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');
812
if (gettype($url) != 'string') {
813
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
816
if (gettype($flags) != 'integer') {
817
phpCAS :: error('type mismatched for parameter $flags (should be `integer\')');
820
$res = $PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt);
822
phpCAS :: traceEnd($res);
827
// ########################################################################
829
// ########################################################################
831
* @addtogroup publicAuth
836
* Set the times authentication will be cached before really accessing the CAS server in gateway mode:
837
* - -1: check only once, and then never again (until you pree login)
839
* - n: check every "n" time
841
* @param $n an integer.
843
public static function setCacheTimesForAuthRecheck($n) {
844
global $PHPCAS_CLIENT;
845
if (!is_object($PHPCAS_CLIENT)) {
846
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
848
if (gettype($n) != 'integer') {
849
phpCAS :: error('type mismatched for parameter $header (should be `string\')');
851
$PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n);
855
* This method is called to check if the user is authenticated (use the gateway feature).
856
* @return TRUE when the user is authenticated; otherwise FALSE.
858
public static function checkAuthentication() {
859
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
861
phpCAS :: traceBegin();
862
if (!is_object($PHPCAS_CLIENT)) {
863
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
866
$auth = $PHPCAS_CLIENT->checkAuthentication();
868
// store where the authentication has been checked and the result
869
$dbg = phpCAS :: backtrace();
870
$PHPCAS_AUTH_CHECK_CALL = array (
872
'file' => $dbg[0]['file'],
873
'line' => $dbg[0]['line'],
874
'method' => __CLASS__ . '::' . __FUNCTION__,
877
phpCAS :: traceEnd($auth);
882
* This method is called to force authentication if the user was not already
883
* authenticated. If the user is not authenticated, halt by redirecting to
886
public static function forceAuthentication() {
887
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
889
phpCAS :: traceBegin();
890
if (!is_object($PHPCAS_CLIENT)) {
891
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
894
$auth = $PHPCAS_CLIENT->forceAuthentication();
896
// store where the authentication has been checked and the result
897
$dbg = phpCAS :: backtrace();
898
$PHPCAS_AUTH_CHECK_CALL = array (
900
'file' => $dbg[0]['file'],
901
'line' => $dbg[0]['line'],
902
'method' => __CLASS__ . '::' . __FUNCTION__,
907
phpCAS :: trace('user is not authenticated, redirecting to the CAS server');
908
$PHPCAS_CLIENT->forceAuthentication();
910
phpCAS :: trace('no need to authenticate (user `' . phpCAS :: getUser() . '\' is already authenticated)');
913
phpCAS :: traceEnd();
918
* This method is called to renew the authentication.
920
public static function renewAuthentication() {
921
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
923
phpCAS :: traceBegin();
924
if (!is_object($PHPCAS_CLIENT)) {
925
phpCAS :: error('this method should not be called before' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
928
// store where the authentication has been checked and the result
929
$dbg = phpCAS :: backtrace();
930
$PHPCAS_AUTH_CHECK_CALL = array (
932
'file' => $dbg[0]['file'],
933
'line' => $dbg[0]['line'],
934
'method' => __CLASS__ . '::' . __FUNCTION__,
938
$PHPCAS_CLIENT->renewAuthentication();
939
phpCAS :: traceEnd();
943
* This method has been left from version 0.4.1 for compatibility reasons.
945
public static function authenticate() {
946
phpCAS :: error('this method is deprecated. You should use ' . __CLASS__ . '::forceAuthentication() instead');
950
* This method is called to check if the user is authenticated (previously or by
951
* tickets given in the URL).
953
* @return TRUE when the user is authenticated.
955
public static function isAuthenticated() {
956
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
958
phpCAS :: traceBegin();
959
if (!is_object($PHPCAS_CLIENT)) {
960
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
963
// call the isAuthenticated method of the global $PHPCAS_CLIENT object
964
$auth = $PHPCAS_CLIENT->isAuthenticated();
966
// store where the authentication has been checked and the result
967
$dbg = phpCAS :: backtrace();
968
$PHPCAS_AUTH_CHECK_CALL = array (
970
'file' => $dbg[0]['file'],
971
'line' => $dbg[0]['line'],
972
'method' => __CLASS__ . '::' . __FUNCTION__,
975
phpCAS :: traceEnd($auth);
980
* Checks whether authenticated based on $_SESSION. Useful to avoid
982
* @return true if authenticated, false otherwise.
983
* @since 0.4.22 by Brendan Arnold
985
public static function isSessionAuthenticated() {
986
global $PHPCAS_CLIENT;
987
if (!is_object($PHPCAS_CLIENT)) {
988
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
990
return ($PHPCAS_CLIENT->isSessionAuthenticated());
994
* This method returns the CAS user's login name.
995
* @warning should not be called only after phpCAS::forceAuthentication()
996
* or phpCAS::checkAuthentication().
998
* @return the login name of the authenticated user
1000
public static function getUser() {
1001
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
1002
if (!is_object($PHPCAS_CLIENT)) {
1003
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1005
if (!$PHPCAS_AUTH_CHECK_CALL['done']) {
1006
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
1008
if (!$PHPCAS_AUTH_CHECK_CALL['result']) {
1009
phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');
1011
return $PHPCAS_CLIENT->getUser();
1015
* This method returns the CAS user's login name.
1016
* @warning should not be called only after phpCAS::forceAuthentication()
1017
* or phpCAS::checkAuthentication().
1019
* @return the login name of the authenticated user
1021
public static function getAttributes() {
1022
global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL;
1023
if (!is_object($PHPCAS_CLIENT)) {
1024
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1026
if (!$PHPCAS_AUTH_CHECK_CALL['done']) {
1027
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()');
1029
if (!$PHPCAS_AUTH_CHECK_CALL['result']) {
1030
phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE');
1032
return $PHPCAS_CLIENT->getAttributes();
1035
* Handle logout requests.
1037
public static function handleLogoutRequests($check_client = true, $allowed_clients = false) {
1038
global $PHPCAS_CLIENT;
1039
if (!is_object($PHPCAS_CLIENT)) {
1040
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1042
return ($PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients));
1046
* This method returns the URL to be used to login.
1047
* or phpCAS::isAuthenticated().
1049
* @return the login name of the authenticated user
1051
public static function getServerLoginURL() {
1052
global $PHPCAS_CLIENT;
1053
if (!is_object($PHPCAS_CLIENT)) {
1054
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1056
return $PHPCAS_CLIENT->getServerLoginURL();
1060
* Set the login URL of the CAS server.
1061
* @param $url the login URL
1062
* @since 0.4.21 by Wyman Chan
1064
public static function setServerLoginURL($url = '') {
1065
global $PHPCAS_CLIENT;
1066
phpCAS :: traceBegin();
1067
if (!is_object($PHPCAS_CLIENT)) {
1068
phpCAS :: error('this method should only be called after
1069
' . __CLASS__ . '::client()');
1071
if (gettype($url) != 'string') {
1072
phpCAS :: error('type mismatched for parameter $url (should be
1075
$PHPCAS_CLIENT->setServerLoginURL($url);
1076
phpCAS :: traceEnd();
1080
* Set the serviceValidate URL of the CAS server.
1081
* Used only in CAS 1.0 validations
1082
* @param $url the serviceValidate URL
1083
* @since 1.1.0 by Joachim Fritschi
1085
public static function setServerServiceValidateURL($url = '') {
1086
global $PHPCAS_CLIENT;
1087
phpCAS :: traceBegin();
1088
if (!is_object($PHPCAS_CLIENT)) {
1089
phpCAS :: error('this method should only be called after
1090
' . __CLASS__ . '::client()');
1092
if (gettype($url) != 'string') {
1093
phpCAS :: error('type mismatched for parameter $url (should be
1096
$PHPCAS_CLIENT->setServerServiceValidateURL($url);
1097
phpCAS :: traceEnd();
1101
* Set the proxyValidate URL of the CAS server.
1102
* Used for all CAS 2.0 validations
1103
* @param $url the proxyValidate URL
1104
* @since 1.1.0 by Joachim Fritschi
1106
public static function setServerProxyValidateURL($url = '') {
1107
global $PHPCAS_CLIENT;
1108
phpCAS :: traceBegin();
1109
if (!is_object($PHPCAS_CLIENT)) {
1110
phpCAS :: error('this method should only be called after
1111
' . __CLASS__ . '::client()');
1113
if (gettype($url) != 'string') {
1114
phpCAS :: error('type mismatched for parameter $url (should be
1117
$PHPCAS_CLIENT->setServerProxyValidateURL($url);
1118
phpCAS :: traceEnd();
1122
* Set the samlValidate URL of the CAS server.
1123
* @param $url the samlValidate URL
1124
* @since 1.1.0 by Joachim Fritschi
1126
public static function setServerSamlValidateURL($url = '') {
1127
global $PHPCAS_CLIENT;
1128
phpCAS :: traceBegin();
1129
if (!is_object($PHPCAS_CLIENT)) {
1130
phpCAS :: error('this method should only be called after
1131
' . __CLASS__ . '::client()');
1133
if (gettype($url) != 'string') {
1134
phpCAS :: error('type mismatched for parameter $url (should be
1137
$PHPCAS_CLIENT->setServerSamlValidateURL($url);
1138
phpCAS :: traceEnd();
1142
* This method returns the URL to be used to login.
1143
* or phpCAS::isAuthenticated().
1145
* @return the login name of the authenticated user
1147
public static function getServerLogoutURL() {
1148
global $PHPCAS_CLIENT;
1149
if (!is_object($PHPCAS_CLIENT)) {
1150
phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()');
1152
return $PHPCAS_CLIENT->getServerLogoutURL();
1156
* Set the logout URL of the CAS server.
1157
* @param $url the logout URL
1158
* @since 0.4.21 by Wyman Chan
1160
public static function setServerLogoutURL($url = '') {
1161
global $PHPCAS_CLIENT;
1162
phpCAS :: traceBegin();
1163
if (!is_object($PHPCAS_CLIENT)) {
1164
phpCAS :: error('this method should only be called after
1165
' . __CLASS__ . '::client()');
1167
if (gettype($url) != 'string') {
1168
phpCAS :: error('type mismatched for parameter $url (should be
1171
$PHPCAS_CLIENT->setServerLogoutURL($url);
1172
phpCAS :: traceEnd();
1176
* This method is used to logout from CAS.
1177
* @params $params an array that contains the optional url and service parameters that will be passed to the CAS server
1180
public static function logout($params = "") {
1181
global $PHPCAS_CLIENT;
1182
phpCAS :: traceBegin();
1183
if (!is_object($PHPCAS_CLIENT)) {
1184
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1186
$parsedParams = array ();
1187
if ($params != "") {
1188
if (is_string($params)) {
1189
phpCAS :: error('method `phpCAS::logout($url)\' is now deprecated, use `phpCAS::logoutWithUrl($url)\' instead');
1191
if (!is_array($params)) {
1192
phpCAS :: error('type mismatched for parameter $params (should be `array\')');
1194
foreach ($params as $key => $value) {
1195
if ($key != "service" && $key != "url") {
1196
phpCAS :: error('only `url\' and `service\' parameters are allowed for method `phpCAS::logout($params)\'');
1198
$parsedParams[$key] = $value;
1201
$PHPCAS_CLIENT->logout($parsedParams);
1203
phpCAS :: traceEnd();
1207
* This method is used to logout from CAS. Halts by redirecting to the CAS server.
1208
* @param $service a URL that will be transmitted to the CAS server
1210
public static function logoutWithRedirectService($service) {
1211
global $PHPCAS_CLIENT;
1212
phpCAS :: traceBegin();
1213
if (!is_object($PHPCAS_CLIENT)) {
1214
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1216
if (!is_string($service)) {
1217
phpCAS :: error('type mismatched for parameter $service (should be `string\')');
1219
$PHPCAS_CLIENT->logout(array (
1220
"service" => $service
1223
phpCAS :: traceEnd();
1227
* This method is used to logout from CAS. Halts by redirecting to the CAS server.
1228
* @param $url a URL that will be transmitted to the CAS server
1230
public static function logoutWithUrl($url) {
1231
global $PHPCAS_CLIENT;
1232
phpCAS :: traceBegin();
1233
if (!is_object($PHPCAS_CLIENT)) {
1234
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1236
if (!is_string($url)) {
1237
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1239
$PHPCAS_CLIENT->logout(array (
1243
phpCAS :: traceEnd();
1247
* This method is used to logout from CAS. Halts by redirecting to the CAS server.
1248
* @param $service a URL that will be transmitted to the CAS server
1249
* @param $url a URL that will be transmitted to the CAS server
1251
public static function logoutWithRedirectServiceAndUrl($service, $url) {
1252
global $PHPCAS_CLIENT;
1253
phpCAS :: traceBegin();
1254
if (!is_object($PHPCAS_CLIENT)) {
1255
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1257
if (!is_string($service)) {
1258
phpCAS :: error('type mismatched for parameter $service (should be `string\')');
1260
if (!is_string($url)) {
1261
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1263
$PHPCAS_CLIENT->logout(array (
1264
"service" => $service,
1268
phpCAS :: traceEnd();
1272
* Set the fixed URL that will be used by the CAS server to transmit the PGT.
1273
* When this method is not called, a phpCAS script uses its own URL for the callback.
1275
* @param $url the URL
1277
public static function setFixedCallbackURL($url = '') {
1278
global $PHPCAS_CLIENT;
1279
phpCAS :: traceBegin();
1280
if (!is_object($PHPCAS_CLIENT)) {
1281
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1283
if (!$PHPCAS_CLIENT->isProxy()) {
1284
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1286
if (gettype($url) != 'string') {
1287
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1289
$PHPCAS_CLIENT->setCallbackURL($url);
1290
phpCAS :: traceEnd();
1294
* Set the fixed URL that will be set as the CAS service parameter. When this
1295
* method is not called, a phpCAS script uses its own URL.
1297
* @param $url the URL
1299
public static function setFixedServiceURL($url) {
1300
global $PHPCAS_CLIENT;
1301
phpCAS :: traceBegin();
1302
if (!is_object($PHPCAS_CLIENT)) {
1303
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1305
if (gettype($url) != 'string') {
1306
phpCAS :: error('type mismatched for parameter $url (should be `string\')');
1308
$PHPCAS_CLIENT->setURL($url);
1309
phpCAS :: traceEnd();
1313
* Get the URL that is set as the CAS service parameter.
1315
public static function getServiceURL() {
1316
global $PHPCAS_CLIENT;
1317
if (!is_object($PHPCAS_CLIENT)) {
1318
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1320
return ($PHPCAS_CLIENT->getURL());
1324
* Retrieve a Proxy Ticket from the CAS server.
1326
public static function retrievePT($target_service, & $err_code, & $err_msg) {
1327
global $PHPCAS_CLIENT;
1328
if (!is_object($PHPCAS_CLIENT)) {
1329
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()');
1331
if (gettype($target_service) != 'string') {
1332
phpCAS :: error('type mismatched for parameter $target_service(should be `string\')');
1334
return ($PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg));
1338
* Set the certificate of the CAS server.
1340
* @param $cert the PEM certificate
1342
public static function setCasServerCert($cert) {
1343
global $PHPCAS_CLIENT;
1344
phpCAS :: traceBegin();
1345
if (!is_object($PHPCAS_CLIENT)) {
1346
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1348
if (gettype($cert) != 'string') {
1349
phpCAS :: error('type mismatched for parameter $cert (should be `string\')');
1351
$PHPCAS_CLIENT->setCasServerCert($cert);
1352
phpCAS :: traceEnd();
1356
* Set the certificate of the CAS server CA.
1358
* @param $cert the CA certificate
1360
public static function setCasServerCACert($cert) {
1361
global $PHPCAS_CLIENT;
1362
phpCAS :: traceBegin();
1363
if (!is_object($PHPCAS_CLIENT)) {
1364
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1366
if (gettype($cert) != 'string') {
1367
phpCAS :: error('type mismatched for parameter $cert (should be `string\')');
1369
$PHPCAS_CLIENT->setCasServerCACert($cert);
1370
phpCAS :: traceEnd();
1374
* Set no SSL validation for the CAS server.
1376
public static function setNoCasServerValidation() {
1377
global $PHPCAS_CLIENT;
1378
phpCAS :: traceBegin();
1379
if (!is_object($PHPCAS_CLIENT)) {
1380
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1382
$PHPCAS_CLIENT->setNoCasServerValidation();
1383
phpCAS :: traceEnd();
1389
* Change CURL options.
1390
* CURL is used to connect through HTTPS to CAS server
1391
* @param $key the option key
1392
* @param $value the value to set
1394
public static function setExtraCurlOption($key, $value) {
1395
global $PHPCAS_CLIENT;
1396
phpCAS :: traceBegin();
1397
if (!is_object($PHPCAS_CLIENT)) {
1398
phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()');
1400
$PHPCAS_CLIENT->setExtraCurlOption($key, $value);
1401
phpCAS :: traceEnd();
1406
// ########################################################################
1408
// ########################################################################
1410
// ########################################################################
1416
* The following pages only show the source documentation.
1420
// ########################################################################
1421
// MODULES DEFINITION
1423
/** @defgroup public User interface */
1425
/** @defgroup publicInit Initialization
1426
* @ingroup public */
1428
/** @defgroup publicAuth Authentication
1429
* @ingroup public */
1431
/** @defgroup publicServices Access to external services
1432
* @ingroup public */
1434
/** @defgroup publicConfig Configuration
1435
* @ingroup public */
1437
/** @defgroup publicLang Internationalization
1438
* @ingroup publicConfig */
1440
/** @defgroup publicOutput HTML output
1441
* @ingroup publicConfig */
1443
/** @defgroup publicPGTStorage PGT storage
1444
* @ingroup publicConfig */
1446
/** @defgroup publicDebug Debugging
1447
* @ingroup public */
1449
/** @defgroup internal Implementation */
1451
/** @defgroup internalAuthentication Authentication
1452
* @ingroup internal */
1454
/** @defgroup internalBasic CAS Basic client features (CAS 1.0, Service Tickets)
1455
* @ingroup internal */
1457
/** @defgroup internalProxy CAS Proxy features (CAS 2.0, Proxy Granting Tickets)
1458
* @ingroup internal */
1460
/** @defgroup internalPGTStorage PGT storage
1461
* @ingroup internalProxy */
1463
/** @defgroup internalPGTStorageFile PGT storage on the filesystem
1464
* @ingroup internalPGTStorage */
1466
/** @defgroup internalCallback Callback from the CAS server
1467
* @ingroup internalProxy */
1469
/** @defgroup internalProxied CAS proxied client features (CAS 2.0, Proxy Tickets)
1470
* @ingroup internal */
1472
/** @defgroup internalConfig Configuration
1473
* @ingroup internal */
1475
/** @defgroup internalOutput HTML output
1476
* @ingroup internalConfig */
1478
/** @defgroup internalLang Internationalization
1479
* @ingroup internalConfig
1481
* To add a new language:
1482
* - 1. define a new constant PHPCAS_LANG_XXXXXX in CAS/CAS.php
1483
* - 2. copy any file from CAS/languages to CAS/languages/XXXXXX.php
1484
* - 3. Make the translations
1487
/** @defgroup internalDebug Debugging
1488
* @ingroup internal */
1490
/** @defgroup internalMisc Miscellaneous
1491
* @ingroup internal */
1493
// ########################################################################
1497
* @example example_simple.php
1500
* @example example_proxy.php
1503
* @example example_proxy2.php
1506
* @example example_lang.php
1509
* @example example_html.php
1512
* @example example_file.php
1515
* @example example_db.php
1518
* @example example_service.php
1521
* @example example_session_proxy.php
1524
* @example example_session_service.php
1527
* @example example_gateway.php
1530
* @example example_custom_urls.php
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') {
1652
phpCAS :: error('type mismatched for parameter $validate_cn (should be `boolean\')');
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