You are here

private function CasValidator::validateVersion2 in CAS 8

Same name and namespace in other branches
  1. 2.x src/Service/CasValidator.php \Drupal\cas\Service\CasValidator::validateVersion2()

Validation of a service ticket for Version 2 of the CAS protocol.

Parameters

string $data: The raw validation response data from CAS server.

Return value

\Drupal\cas\CasPropertyBag Contains user info from the CAS server.

Throws

\Drupal\cas\Exception\CasValidateException Thrown if there was a problem parsing the validation data.

1 call to CasValidator::validateVersion2()
CasValidator::validateTicket in src/Service/CasValidator.php
Validate the service ticket parameter present in the request.

File

src/Service/CasValidator.php, line 228

Class

CasValidator
Class CasValidator.

Namespace

Drupal\cas\Service

Code

private function validateVersion2($data) {
  $dom = new \DOMDocument();
  $dom->preserveWhiteSpace = FALSE;
  $dom->encoding = "utf-8";

  // Suppress errors from this function, as we intend to throw our own
  // exception.
  if (@$dom
    ->loadXML($data) === FALSE) {
    throw new CasValidateException("XML from CAS server is not valid.");
  }
  $failure_elements = $dom
    ->getElementsByTagName('authenticationFailure');
  if ($failure_elements->length > 0) {

    // Failed validation, extract the message and throw exception.
    $failure_element = $failure_elements
      ->item(0);
    $error_code = $failure_element
      ->getAttribute('code');
    $error_msg = $failure_element->nodeValue;
    throw new CasValidateException("Error Code " . trim($error_code) . ": " . trim($error_msg));
  }
  $success_elements = $dom
    ->getElementsByTagName("authenticationSuccess");
  if ($success_elements->length === 0) {

    // All responses should have either an authenticationFailure
    // or authenticationSuccess node.
    throw new CasValidateException("XML from CAS server is not valid.");
  }

  // There should only be one success element, grab it and extract username.
  $success_element = $success_elements
    ->item(0);
  $user_element = $success_element
    ->getElementsByTagName("user");
  if ($user_element->length == 0) {
    throw new CasValidateException("No user found in ticket validation response.");
  }
  $username = $user_element
    ->item(0)->nodeValue;
  $this->casHelper
    ->log(LogLevel::DEBUG, "Extracted username %user from validation response.", [
    '%user' => $username,
  ]);
  $property_bag = new CasPropertyBag($username);

  // If the server provided any attributes, parse them out into the property
  // bag.
  $attribute_elements = $dom
    ->getElementsByTagName("attributes");
  if ($attribute_elements->length > 0) {
    $property_bag
      ->setAttributes($this
      ->parseAttributes($attribute_elements));
  }

  // Look for a proxy chain, and if it exists, validate it against config.
  $proxy_chain = $success_element
    ->getElementsByTagName("proxy");
  if ($this->settings
    ->get('proxy.can_be_proxied') && $proxy_chain->length > 0) {
    $this
      ->verifyProxyChain($proxy_chain);
  }
  if ($this->settings
    ->get('proxy.initialize')) {

    // Extract the PGTIOU from the XML.
    $pgt_element = $success_element
      ->getElementsByTagName("proxyGrantingTicket");
    if ($pgt_element->length == 0) {
      throw new CasValidateException("Proxy initialized, but no PGTIOU provided in response.");
    }
    $pgt = $pgt_element
      ->item(0)->nodeValue;
    $this->casHelper
      ->log(LogLevel::DEBUG, "Extracted PGT %pgt from validation response.", [
      '%pgt' => $pgt,
    ]);
    $property_bag
      ->setPgt($pgt);
  }
  return $property_bag;
}