function authenticate($user, $username, $password)
 {
     // Don't re-authenticate if already authenticated
     if (is_a($user, 'WP_User')) {
         return $user;
     }
     if (!isset($_GET['id_token'])) {
         if (isset($_GET['error'])) {
             // The attempt to get an authorization code failed (i.e., the reply from the STS was "No.")
             return new WP_Error($_GET['error'], sprintf(__('ERROR: Access denied to Azure Active Directory. %s', 'aad-sso'), $_GET['error_description']));
         }
         return $user;
     }
     try {
         AADSSO_AuthorizationHelper::$base_uri = $this->settings->base_uri;
         $jwt = AADSSO_AuthorizationHelper::validate_id_token($_GET['id_token']);
     } catch (Exception $e) {
         return new WP_Error('invalid_id_token', sprintf(__('ERROR: Invalid id_token. %s', 'aad-sso'), $e->getMessage()));
     }
     if (!isset($jwt->altsecid) || !$jwt->altsecid) {
         return new WP_Error('missing_altsecid_property', sprintf(__('%s is not a valid account. Please sign-out first and then sign-in with your Windows Live ID.', 'aad-sso'), $jwt->unique_name));
     }
     if (!wp_verify_nonce($jwt->nonce, self::NONCE_NAME)) {
         return new WP_Error('nonce_fail', sprintf(__('NONCE_NAME mismatch. Expecting %s', 'aad-sso'), self::NONCE_NAME));
     }
     if ($jwt->aud != $this->settings->client_id) {
         //	Need to check [aud] is the same as the client id
         return new WP_Error('client_id_mismatch', sprintf(__('ERROR: aud ( %s ) does not match Client ID', 'aad-sso'), $jwt->aud));
     }
     if (strpos($jwt->iss, 'sts.windows.net') == false && strpos($jwt->iss, 'sts.windows-ppe.net') == false) {
         //	[iss] contains sts.windows.net or sts.windows-ppe.net
         return new WP_Error('issuer_mismatch', sprintf(__('ERROR: Issuer was %s, expected windows.net', 'aad-sso'), $jwt->iss));
     }
     if ((int) $jwt->iat > (int) time()) {
         //	[iat] must not be in the future
         return new WP_Error('issuing_time_error', sprintf(__('ERROR: Account must be issued in the past, was issued at %s.', 'aad-sso'), $jwt->iat));
     }
     if ((int) $jwt->exp <= (int) time()) {
         //	[exp] must not be in the past
         return new WP_Error('issuing_is_expired', sprintf(__('ERROR: Account has expired on %s', 'aad-sso'), $jwt->exp));
     }
     // Try to find an existing user in WP with the altsecid of the currect AAD user
     $user = $this->get_user_by_aad_id($jwt->altsecid);
     // If we have a user, log them in
     if (!empty($user) && is_a($user, 'WP_User')) {
         // At this point, we have an authorization code, an access token and the user exists in WordPress.
         $user = apply_filters('aad_sso_found_user', $user, $jwt);
         return $user;
     }
     /*
      * No user found. Now decide if we are allowed to create a new
      * user or not. Will use the WordPress setting from Settings > General
      */
     $reg_open = get_option('users_can_register');
     $override_reg = apply_filters('aad_override_user_registration', $this->settings->override_user_registration, $jwt);
     if (!$reg_open && !$override_reg) {
         return new WP_Error('user_not_registered', sprintf(__('ERROR: The authenticated user %s is not a registered user in this blog.', 'aad-sso'), $jwt));
     }
     $email = $this->get_jwt_email($jwt);
     if (is_wp_error($email)) {
         return $email;
     }
     $username = explode('@', $email);
     $username = apply_filters('aad_sso_login_username', $username[0], $jwt);
     $username = get_user_by('login', $username) ? 'aadsso-' . sanitize_text_field($jwt->altsecid) : $username;
     // Setup the minimum required user data
     $userdata = array('user_login' => wp_slash($username), 'user_email' => wp_slash($email), 'user_pass' => wp_generate_password(20, true), 'first_name' => isset($jwt->given_name) ? esc_html($jwt->given_name) : '', 'last_name' => isset($jwt->family_name) ? esc_html($jwt->family_name) : '', 'role' => $this->settings->default_wp_role ? $this->settings->default_wp_role : 'subscriber');
     $userdata['display_name'] = $userdata['nickname'] = $userdata['first_name'] && $userdata['last_name'] ? $userdata['first_name'] . ' ' . $userdata['last_name'] : $userdata['first_name'];
     // Allow user-creation override
     $user = apply_filters('aad_sso_new_user_override', null, $userdata, $jwt);
     // If we have a user, log them in
     if (!empty($user) && is_a($user, 'WP_User')) {
         // At this point, the user exists in WordPress.
         $user = apply_filters('aad_sso_found_user', $user, $jwt);
         return $user;
     }
     $new_user_id = wp_insert_user($userdata);
     if (is_wp_error($new_user_id)) {
         return $new_user_id;
     }
     // update usermeta so we know who the user is next time
     update_user_meta($new_user_id, $this->user_id_meta_key, sanitize_text_field($jwt->altsecid));
     $user = new WP_User($new_user_id);
     // @todo do_action new_user
     $user = apply_filters('aad_sso_new_user', $user, $jwt);
     return $user;
 }
 /**
  * Generates the URL used to initiate a sign-in with Azure AD.
  *
  * @return string The authorization URL used to initiate a sign-in to Azure AD.
  */
 function get_login_url()
 {
     $antiforgery_id = com_create_guid();
     $_SESSION['aadsso_antiforgery-id'] = $antiforgery_id;
     return AADSSO_AuthorizationHelper::get_authorization_url($this->settings, $antiforgery_id);
 }
 function get_login_url()
 {
     $antiforgery_id = com_create_guid();
     $_SESSION[self::ANTIFORGERY_ID_KEY] = $antiforgery_id;
     return AADSSO_AuthorizationHelper::getAuthorizationURL($this->settings, $antiforgery_id);
 }