📄 client.php
字号:
} /** * This method sets the callback url. * * @param $callback_url url to set callback * * @private */ function setCallbackURL($url) { return $this->_callback_url = $url; } /** * This method is called by CASClient::CASClient() when running in callback * mode. It stores the PGT and its PGT Iou, prints its output and halts. * * @private */ function callback() { phpCAS::traceBegin(); $this->printHTMLHeader('phpCAS callback'); $pgt_iou = $_GET['pgtIou']; $pgt = $_GET['pgtId']; phpCAS::trace('Storing PGT `'.$pgt.'\' (id=`'.$pgt_iou.'\')'); echo '<p>Storing PGT `'.$pgt.'\' (id=`'.$pgt_iou.'\').</p>'; $this->storePGT($pgt,$pgt_iou); $this->printHTMLFooter(); phpCAS::traceExit(); } /** @} */ // ######################################################################## // PGT STORAGE // ######################################################################## /** * @addtogroup internalPGTStorage * @{ */ /** * an instance of a class inheriting of PGTStorage, used to deal with PGT * storage. Created by CASClient::setPGTStorageFile() or CASClient::setPGTStorageDB(), used * by CASClient::setPGTStorageFile(), CASClient::setPGTStorageDB() and CASClient::initPGTStorage(). * * @hideinitializer * @private */ var $_pgt_storage = null; /** * This method is used to initialize the storage of PGT's. * Halts on error. * * @private */ function initPGTStorage() { // if no SetPGTStorageXxx() has been used, default to file if ( !is_object($this->_pgt_storage) ) { $this->setPGTStorageFile(); } // initializes the storage $this->_pgt_storage->init(); } /** * This method stores a PGT. Halts on error. * * @param $pgt the PGT to store * @param $pgt_iou its corresponding Iou * * @private */ function storePGT($pgt,$pgt_iou) { // ensure that storage is initialized $this->initPGTStorage(); // writes the PGT $this->_pgt_storage->write($pgt,$pgt_iou); } /** * This method reads a PGT from its Iou and deletes the corresponding storage entry. * * @param $pgt_iou the PGT Iou * * @return The PGT corresponding to the Iou, FALSE when not found. * * @private */ function loadPGT($pgt_iou) { // ensure that storage is initialized $this->initPGTStorage(); // read the PGT return $this->_pgt_storage->read($pgt_iou); } /** * This method is used to tell phpCAS to store the response of the * CAS server to PGT requests onto the filesystem. * * @param $format the format used to store the PGT's (`plain' and `xml' allowed) * @param $path the path where the PGT's should be stored * * @public */ function setPGTStorageFile($format='', $path='') { // check that the storage has not already been set if ( is_object($this->_pgt_storage) ) { phpCAS::error('PGT storage already defined'); } // create the storage object $this->_pgt_storage = &new PGTStorageFile($this,$format,$path); } /** * This method is used to tell phpCAS to store the response of the * CAS server to PGT requests into a database. * @note The connection to the database is done only when needed. * As a consequence, bad parameters are detected only when * initializing PGT storage. * * @param $user the user to access the data with * @param $password the user's password * @param $database_type the type of the database hosting the data * @param $hostname the server hosting the database * @param $port the port the server is listening on * @param $database the name of the database * @param $table the name of the table storing the data * * @public */ function setPGTStorageDB($user, $password, $database_type, $hostname, $port, $database, $table) { // check that the storage has not already been set if ( is_object($this->_pgt_storage) ) { phpCAS::error('PGT storage already defined'); } // warn the user that he should use file storage... trigger_error('PGT storage into database is an experimental feature, use at your own risk',E_USER_WARNING); // create the storage object $this->_pgt_storage = & new PGTStorageDB($this,$user,$password,$database_type,$hostname,$port,$database,$table); } // ######################################################################## // PGT VALIDATION // ######################################################################## /** * This method is used to validate a PGT; halt on failure. * * @param $validate_url the URL of the request to the CAS server. * @param $text_response the response of the CAS server, as is (XML text); result * of CASClient::validateST() or CASClient::validatePT(). * @param $tree_response the response of the CAS server, as a DOM XML tree; result * of CASClient::validateST() or CASClient::validatePT(). * * @return bool TRUE when successfull, halt otherwise by calling CASClient::authError(). * * @private */ function validatePGT(&$validate_url,$text_response,$tree_response) { phpCAS::traceBegin(); if ( sizeof($arr = $tree_response->get_elements_by_tagname("proxyGrantingTicket")) == 0) { phpCAS::trace('<proxyGrantingTicket> not found'); // authentication succeded, but no PGT Iou was transmitted $this->authError('Ticket validated but no PGT Iou transmitted', $validate_url, FALSE/*$no_response*/, FALSE/*$bad_response*/, $text_response); } else { // PGT Iou transmitted, extract it $pgt_iou = trim($arr[0]->get_content()); $pgt = $this->loadPGT($pgt_iou); if ( $pgt == FALSE ) { phpCAS::trace('could not load PGT'); $this->authError('PGT Iou was transmitted but PGT could not be retrieved', $validate_url, FALSE/*$no_response*/, FALSE/*$bad_response*/, $text_response); } $this->setPGT($pgt); } phpCAS::traceEnd(TRUE); return TRUE; } // ######################################################################## // PGT VALIDATION // ######################################################################## /** * This method is used to retrieve PT's from the CAS server thanks to a PGT. * * @param $target_service the service to ask for with the PT. * @param $err_code an error code (PHPCAS_SERVICE_OK on success). * @param $err_msg an error message (empty on success). * * @return a Proxy Ticket, or FALSE on error. * * @private */ function retrievePT($target_service,&$err_code,&$err_msg) { phpCAS::traceBegin(); // by default, $err_msg is set empty and $pt to TRUE. On error, $pt is // set to false and $err_msg to an error message. At the end, if $pt is FALSE // and $error_msg is still empty, it is set to 'invalid response' (the most // commonly encountered error). $err_msg = ''; // build the URL to retrieve the PT// $cas_url = $this->getServerProxyURL().'?targetService='.preg_replace('/&/','%26',$target_service).'&pgt='.$this->getPGT(); $cas_url = $this->getServerProxyURL().'?targetService='.urlencode($target_service).'&pgt='.$this->getPGT(); // open and read the URL if ( !$this->readURL($cas_url,''/*cookies*/,$headers,$cas_response,$err_msg) ) { phpCAS::trace('could not open URL \''.$cas_url.'\' to validate ('.$err_msg.')'); $err_code = PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE; $err_msg = 'could not retrieve PT (no response from the CAS server)'; phpCAS::traceEnd(FALSE); return FALSE; } $bad_response = FALSE; if ( !$bad_response ) { // read the response of the CAS server into a DOM object if ( !($dom = @domxml_open_mem($cas_response))) { phpCAS::trace('domxml_open_mem() failed'); // read failed $bad_response = TRUE; } } if ( !$bad_response ) { // read the root node of the XML tree if ( !($root = $dom->document_element()) ) { phpCAS::trace('document_element() failed'); // read failed $bad_response = TRUE; } } if ( !$bad_response ) { // insure that tag name is 'serviceResponse' if ( $root->node_name() != 'serviceResponse' ) { phpCAS::trace('node_name() failed'); // bad root node $bad_response = TRUE; } } if ( !$bad_response ) { // look for a proxySuccess tag if ( sizeof($arr = $root->get_elements_by_tagname("proxySuccess")) != 0) { // authentication succeded, look for a proxyTicket tag if ( sizeof($arr = $root->get_elements_by_tagname("proxyTicket")) != 0) { $err_code = PHPCAS_SERVICE_OK; $err_msg = ''; phpCAS::trace('original PT: '.trim($arr[0]->get_content())); $pt = trim($arr[0]->get_content()); phpCAS::traceEnd($pt); return $pt; } else { phpCAS::trace('<proxySuccess> was found, but not <proxyTicket>'); } } // look for a proxyFailure tag else if ( sizeof($arr = $root->get_elements_by_tagname("proxyFailure")) != 0) { // authentication failed, extract the error $err_code = PHPCAS_SERVICE_PT_FAILURE; $err_msg = 'PT retrieving failed (code=`' .$arr[0]->get_attribute('code') .'\', message=`' .trim($arr[0]->get_content()) .'\')'; phpCAS::traceEnd(FALSE); return FALSE; } else { phpCAS::trace('neither <proxySuccess> nor <proxyFailure> found'); } } // at this step, we are sure that the response of the CAS server was ill-formed $err_code = PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE; $err_msg = 'Invalid response from the CAS server (response=`'.$cas_response.'\')'; phpCAS::traceEnd(FALSE); return FALSE; } // ######################################################################## // ACCESS TO EXTERNAL SERVICES // ######################################################################## /** * This method is used to acces a remote URL. * * @param $url the URL to access. * @param $cookies an array containing cookies strings such as 'name=val' * @param $headers an array containing the HTTP header lines of the response * (an empty array on failure). * @param $body the body of the response, as a string (empty on failure). * @param $err_msg an error message, filled on failure. * * @return TRUE on success, FALSE otherwise (in this later case, $err_msg * contains an error message). * * @private */ function readURL($url,$cookies,&$headers,&$body,&$err_msg) { phpCAS::traceBegin(); $headers = ''; $body = ''; $err_msg = ''; $res = TRUE; // initialize the CURL session $ch = curl_init($url); // verify the the server's certificate corresponds to its name curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // but do not verify the certificate itself curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // return the CURL output into a variable curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // include the HTTP header with the body curl_setopt($ch, CURLOPT_HEADER, 1); // add cookies headers if ( is_array($cookies) ) { curl_setopt($ch,CURLOPT_COOKIE,implode(';',$cookies)); } // perform the query $buf = curl_exec ($ch); if ( $buf === FALSE ) { phpCAS::trace('cur_exec() failed'); $err_msg = 'CURL error #'.curl_errno($ch).': '.curl_error($ch); // close the CURL session curl_close ($ch); $res = FALSE; } else { // close the CURL session curl_close ($ch); // find the end of the headers // note: strpos($str,"\n\r\n\r") does not work (?) $pos = FALSE; for ($i=0; $i<strlen($buf); $i++) { if ( $buf[$i] == chr(13) ) if ( $buf[$i+1] == chr(10) ) if ( $buf[$i+2] == chr(13) ) if ( $buf[$i+3] == chr(10) ) { // header found $pos = $i; break; } } if ( $pos === FALSE ) { // end of header not found $err_msg = 'no header found'; phpCAS::trace($err_msg); $res = FALSE; } else { // extract headers into an array $headers = preg_split ("/[\n\r]+/",substr($buf,0,$pos)); // extract body into a string $body = substr($buf,$pos+4); } } phpCAS::traceEnd($res); return $res; } /** * This method is used to access an HTTP[S] service. * * @param $url the service to access. * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT AVAILABLE. * @param $output the output of the service (also used to give an error * message on failure). * * @return TRUE on success, FALSE otherwise (in this later case, $err_code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -