You are here

public function MiniOrangeAcs::processSamlResponse in SAML SP 2.0 Single Sign On (SSO) - SAML Service Provider 8

The function processSamlResponse.

File

src/MiniOrangeAcs.php, line 16

Class

MiniOrangeAcs
The MiniOrangeAcs class.

Namespace

Drupal\miniorange_saml

Code

public function processSamlResponse($post, $acs_url, $cert_fingerprint, $issuer, $base_url, $spEntityId, $username_attribute, $custom_attributes, $custom_roles) {
  if (array_key_exists('SAMLResponse', $post)) {
    $saml_response = $post['SAMLResponse'];
  }
  else {
    throw new Exception('Missing SAMLRequest or SAMLResponse parameter.');
  }
  $RelayState = $base_url;
  if (array_key_exists('RelayState', $post) && $post['RelayState'] != 'testValidate') {
    $RelayState = $post['RelayState'];
  }
  $saml_response = base64_decode($saml_response);
  $document = new DOMDocument();
  $document
    ->loadXML($saml_response);
  $saml_response_xml = $document->firstChild;
  if ($RelayState == "showSamlResponse") {
    Utilities::Print_SAML_Request($saml_response, "displaySamlResponse");
  }
  $doc = $document->documentElement;
  $xpath = new DOMXpath($document);
  $xpath
    ->registerNamespace('samlp', 'urn:oasis:names:tc:SAML:2.0:protocol');
  $xpath
    ->registerNamespace('saml', 'urn:oasis:names:tc:SAML:2.0:assertion');
  $status = $xpath
    ->query('/samlp:Response/samlp:Status/samlp:StatusCode', $doc);
  $statusString = $status
    ->item(0)
    ->getAttribute('Value');
  $statusChildString = '';
  if ($status
    ->item(0)->firstChild !== null) {
    $statusChildString = $status
      ->item(0)->firstChild
      ->getAttribute('Value');
  }
  $stat = explode(":", $statusString);
  $status = $stat[7];
  if ($status != "Success") {
    if (!empty($statusChildString)) {
      $stat = explode(":", $statusChildString);
      $status = $stat[7];
    }
    $this
      ->show_error_message($status, $post);
  }
  $cert_fingerprint = XMLSecurityKey::getRawThumbprint($cert_fingerprint);
  $saml_response = new SAML2_Response($saml_response_xml);
  $cert_fingerprint = preg_replace('/\\s+/', '', $cert_fingerprint);
  $response_signature_data = $saml_response
    ->getSignatureData();
  $assertion_signature_data = current($saml_response
    ->getAssertions())
    ->getSignatureData();
  if (is_null($response_signature_data) && is_null($assertion_signature_data)) {
    echo 'Neither response nor assertion is signed';
    exit;
  }
  if (!is_null($response_signature_data)) {
    $response_valid_signature = Utilities::processResponse($acs_url, $cert_fingerprint, $response_signature_data, $saml_response);
    if (!$response_valid_signature) {
      echo 'Invalid Signature in SAML Response';
      exit;
    }
  }
  if (!is_null($assertion_signature_data)) {
    $assertion_valid_signature = Utilities::processResponse($acs_url, $cert_fingerprint, $assertion_signature_data, $saml_response);
    if (!$assertion_valid_signature) {
      echo 'Invalid Signature in SAML Assertion';
      exit;
    }
  }
  Utilities::validateIssuerAndAudience($saml_response, $spEntityId, $issuer, $base_url);
  $attrs = current($saml_response
    ->getAssertions())
    ->getAttributes();
  if ($username_attribute != 'NameID') {
    if (array_key_exists($username_attribute, $attrs)) {
      $username = $attrs[$username_attribute][0];
    }
    else {

      // Get NameID value if username attribute doesnt exist in response.
      $username = current(current($saml_response
        ->getAssertions())
        ->getNameId());
    }
  }
  else {

    // Get Name ID value.
    $username = current(current($saml_response
      ->getAssertions())
      ->getNameId());
  }

  // Get Email.
  $email_attribute = \Drupal::config('miniorange_saml.settings')
    ->get('miniorange_saml_email_attribute');
  if ($email_attribute == 'NameID') {
    $email_value = current(current($saml_response
      ->getAssertions())
      ->getNameId());
  }
  else {
    $email_value = $attrs[$email_attribute][0];
  }

  // Get RelayState if any.
  $relay_state = $base_url;
  if (array_key_exists('RelayState', $post)) {
    if ($post['RelayState'] == 'testValidate') {
      $this
        ->showTestResults($username, $attrs);
    }
    else {
      if ($post['RelayState'] != '/') {
        $relay_state = $post['RelayState'];
      }
    }
  }
  $sessionIndex = current($saml_response
    ->getAssertions())
    ->getSessionIndex();
  $nameId = current(current($saml_response
    ->getAssertions())
    ->getNameId());

  /*Custom Attributes*/
  $custom_attribute_values = array();
  foreach ($custom_attributes as $key => $value) {
    if (array_key_exists($value, $attrs)) {
      $attr_value = $attrs[$value][0];
      $custom_attribute_values[$key] = $attr_value;
    }
  }
  $response = array();
  $response['email'] = $email_value;
  $response['username'] = $username;
  $response['NameID'] = $nameId;
  $response['sessionIndex'] = $sessionIndex;
  if (!empty($relay_state)) {
    $response['relay_state'] = $relay_state;
  }
  return $response;
}