You are here

function samlauth_acs in SAML Authentication 7

Menu callback for /saml/acs.

1 string reference to 'samlauth_acs'
samlauth_menu in ./samlauth.module
Implements hook_menu().

File

./samlauth.module, line 326
Provides SAML authentication capabilities.

Code

function samlauth_acs() {
  $account = FALSE;
  try {
    $auth = samlauth_get_saml2_auth();
    $auth
      ->processResponse();
    $errors = $auth
      ->getErrors();
    if (!empty($errors)) {
      $reason = $auth
        ->getLastErrorReason();

      // Special handling for passive authentication requests: if they fail it
      // means the user is not logged in, so redirect them to our login form.
      if ($reason == 'The status code of the Response was not Success, was Responder -> Cannot authenticate Subject in Passive Mode') {
        watchdog('samlauth', 'Passive authentication failed, redirecting to login form. @reason', [
          '@reason' => $reason,
        ], WATCHDOG_INFO);
        drupal_goto('user/login', array(
          'query' => array(
            'saml' => 'anonymous',
          ),
        ));
      }
      else {
        throw new Exception('ACS error: ' . implode(', ', $errors) . " Reason: {$reason}");
      }
    }
    if (!$auth
      ->isAuthenticated()) {
      throw new Exception('SAML user is not authenticated.');
    }

    // Get the attributes returned by the IdP.
    $saml_data = $auth
      ->getAttributes();

    // First, let's see if we have a user.
    $unique_id_attribute = variable_get('samlauth_unique_id_attribute', 'eduPersonTargetedID');

    // If the configured unique id attribute is not present, then bail out early.
    if (!isset($saml_data[$unique_id_attribute][0])) {
      watchdog('samlauth', 'Configured unique ID is not present in the SAML response: <pre>@response</pre>', array(
        '@response' => print_r($saml_data, TRUE),
      ), WATCHDOG_ERROR);
      throw new Exception('Configured unique ID is not present in the SAML response.');
    }

    // Try to find the user using the ID that we are given.
    $unique_id = $saml_data[$unique_id_attribute][0];
    $uid = samlauth_find_uid_by_unique_id($unique_id);
    if ($uid) {

      // Load the user that was found.
      $account = user_load($uid);

      // If the account is blocked, bail out.
      if ($account->status != 1) {
        throw new Exception("User account is blocked.");
      }
    }
    else {
      $mail_attribute = variable_get('samlauth_user_mail_attribute', 'email');
      if (variable_get('samlauth_map_users_email', FALSE) && ($account = user_load_by_mail($saml_data[$mail_attribute]))) {
        samlauth_associate_saml_id_with_account($unique_id, $account);
      }
      elseif (variable_get('samlauth_create_users', FALSE)) {
        $account = samlauth_create_user_from_saml_data($saml_data);
      }
      else {
        throw new Exception('No existing user account matches the SAML ID provided. This authentication service is not configured to create new accounts.');
      }
    }
  } catch (Exception $e) {
    drupal_set_message($e
      ->getMessage(), 'error');
    watchdog_exception('samlauth', $e);
    drupal_goto();
  }

  // If we're good to continue, log the user in.
  global $user;
  $user = $account;
  user_login_finalize();

  // Store the authentication details in the user's session, we need it later
  // when logging out.
  $_SESSION['samlauth']['nameId'] = $auth
    ->getNameId();
  $_SESSION['samlauth']['nameIdFormat'] = $auth
    ->getNameIdFormat();
  $_SESSION['samlauth']['nameIdNameQualifier'] = $auth
    ->getNameIdNameQualifier();
  $_SESSION['samlauth']['sessionIndex'] = $auth
    ->getSessionIndex();
  drupal_goto();
}