/** * Validate the service ticket parameter present in the request. * * This method will return the username of the user if valid, and raise an * exception if the ticket is not found or not valid. * * @param string $ticket * The CAS authentication ticket to validate. * @param array $service_params * An array of query string parameters to add to the service URL. * * @return array * An array containing validation result data from the CAS server. * * @throws CasValidateException * Thrown if there was a problem making the validation request or * if there was a local configuration issue. */ public function validateTicket($ticket, $service_params = array()) { $options = array(); $verify = $this->casHelper->getSslVerificationMethod(); switch ($verify) { case CasHelper::CA_CUSTOM: $cert = $this->casHelper->getCertificateAuthorityPem(); $options['verify'] = $cert; break; case CasHelper::CA_NONE: $options['verify'] = FALSE; break; case CasHelper::CA_DEFAULT: default: // This triggers for CasHelper::CA_DEFAULT. $options['verify'] = TRUE; } $validate_url = $this->casHelper->getServerValidateUrl($ticket, $service_params); $this->casHelper->log("Attempting to validate service ticket using URL {$validate_url}"); try { $response = $this->httpClient->get($validate_url, $options); $response_data = $response->getBody()->__toString(); $this->casHelper->log("Validation response received from CAS server: " . htmlspecialchars($response_data)); } catch (RequestException $e) { throw new CasValidateException("Error with request to validate ticket: " . $e->getMessage()); } $protocol_version = $this->casHelper->getCasProtocolVersion(); switch ($protocol_version) { case "1.0": return $this->validateVersion1($response_data); case "2.0": return $this->validateVersion2($response_data); } throw new CasValidateException('Unknown CAS protocol version specified: ' . $protocol_version); }
/** * Handles a request to either validate a user login or log a user out. * * The path that this controller/action handle are always set to the "service" * when authenticating with the CAS server, so CAS server communicates back to * the Drupal site using this controller. */ public function handle() { $request = $this->requestStack->getCurrentRequest(); // First, check if this is a single-log-out (SLO) request from the server. if ($request->request->has('logoutRequest')) { $this->casHelper->log("Logout request: passing to casLogout::handleSlo"); $this->casLogout->handleSlo($request->request->get('logoutRequest')); // Always return a 200 code. CAS Server doesn’t care either way what // happens here, since it is a fire-and-forget approach taken. return Response::create('', 200); } // Our CAS Subscriber, which implements forced redirect and gateway, will // set this query string param which indicates we should disable the // subscriber on the next redirect. This prevents an infinite redirect loop. if ($request->query->has('cas_temp_disable')) { $this->casHelper->log("Temp disable flag set, set session flag."); $_SESSION['cas_temp_disable'] = TRUE; } // Check if there is a ticket parameter. If there isn't, we could be // returning from a gateway request and the user may not be logged into CAS. // Just redirect away from here. if (!$request->query->has('ticket')) { $this->casHelper->log("No ticket detected, move along."); $this->handleReturnToParameter($request); return RedirectResponse::create($this->urlGenerator->generate('<front>')); } $ticket = $request->query->get('ticket'); // Our CAS service will need to reconstruct the original service URL // when validating the ticket. We always know what the base URL for // the service URL (it's this page), but there may be some query params // attached as well (like a destination param) that we need to pass in // as well. So, detach the ticket param, and pass the rest off. $service_params = $request->query->all(); unset($service_params['ticket']); $cas_version = $this->casHelper->getCasProtocolVersion(); $this->casHelper->log("Configured to use CAS protocol version: {$cas_version}"); try { $cas_validation_info = $this->casValidator->validateTicket($cas_version, $ticket, $service_params); } catch (CasValidateException $e) { // Validation failed, redirect to homepage and set message. $this->setMessage(t('There was a problem validating your login, please contact a site administrator.'), 'error'); $this->handleReturnToParameter($request); return RedirectResponse::create($this->urlGenerator->generate('<front>')); } try { $this->casLogin->loginToDrupal($cas_validation_info, $ticket); if ($this->casHelper->isProxy() && $cas_validation_info->getPgt()) { $this->casHelper->log("Storing PGT information for this session."); $this->casHelper->storePGTSession($cas_validation_info->getPgt()); } $this->setMessage(t('You have been logged in.')); } catch (CasLoginException $e) { $this->setMessage(t('There was a problem logging in, please contact a site administrator.'), 'error'); } $this->handleReturnToParameter($request); return RedirectResponse::create($this->urlGenerator->generate('<front>')); }
/** * Test getting the CAS protocol version. * * @covers ::getCasProtocolVersion * @covers ::__construct */ public function testGetCasProtocolVersion() { $config_factory = $this->getConfigFactoryStub(array('cas.settings' => array('server.hostname' => 'example.com', 'server.port' => 443, 'server.path' => '/cas', 'server.version' => '1.0'))); $cas_helper = new CasHelper($config_factory, $this->urlGenerator, $this->connection, $this->loggerFactory, $this->session); $this->assertEquals('1.0', $cas_helper->getCasProtocolVersion()); }