function authenticate($user, $username, $password)
 {
     // Don't re-authenticate if already authenticated
     if (is_a($user, 'WP_User')) {
         return $user;
     }
     if (isset($_GET['code'])) {
         $antiforgery_id = $_SESSION[self::ANTIFORGERY_ID_KEY];
         $state_is_missing = !isset($_GET['state']);
         $state_doesnt_match = $_GET['state'] != $antiforgery_id;
         if ($state_is_missing || $state_doesnt_match) {
             return new WP_Error('antiforgery_id_mismatch', sprintf('ANTIFORGERY_ID mismatch. Expecting %s', $antiforgery_id));
         }
         // Looks like we got an authorization code, let's try to get an access token with it
         $token = AADSSO_AuthorizationHelper::getAccessToken($_GET['code'], $this->settings);
         // Happy path
         if (isset($token->access_token)) {
             try {
                 $jwt = AADSSO_AuthorizationHelper::validateIdToken($token->id_token, $this->settings, $antiforgery_id);
             } catch (Exception $e) {
                 return new WP_Error('invalid_id_token', sprintf('ERROR: Invalid id_token. %s', $e->getMessage()));
             }
             // Invoke any configured matching and auto-provisioning strategy and get the user.
             $user = $this->getWPUserFromAADUser($jwt);
             if (is_a($user, 'WP_User')) {
                 // At this point, we have an authorization code, an access token and the user
                 // exists in WordPress (either because it already existed, or we created it
                 // on-the-fly. All that's left is to set the roles based on group membership.
                 if ($this->settings->enable_aad_group_to_wp_role) {
                     $user = $this->updateUserRoles($user, $jwt->upn, $jwt->tid);
                 }
             }
         } elseif (isset($token->error)) {
             // Unable to get an access token (although we did get an authorization code)
             return new WP_Error($token->error, sprintf('ERROR: Could not get an access token to Azure Active Directory. %s', $token->error_description));
         } else {
             // None of the above, I have no idea what happened.
             return new WP_Error('unknown', 'ERROR: An unknown error occured.');
         }
     } elseif (isset($_GET['error'])) {
         // The attempt to get an authorization code failed.
         return new WP_Error($_GET['error'], sprintf('ERROR: Access denied to Azure Active Directory. %s', $_GET['error_description']));
     }
     return $user;
 }