diff --git a/api/api.inc.php b/api/api.inc.php
index ecde89f9b7d8c6c7aa6a6f1082c39fd5a9484c6d..fac03bccd1d848308809e78343838d5401325771 100644
--- a/api/api.inc.php
+++ b/api/api.inc.php
@@ -17,8 +17,6 @@ file_exists('../main.inc.php') or die('System Error');
 
 // Disable sessions for the API. API should be considered stateless and
 // shouldn't chew up database records to store sessions
-if (!function_exists('noop')) { function noop() {} }
-session_set_save_handler('noop','noop','noop','noop','noop','noop');
 define('DISABLE_SESSION', true);
 
 require_once('../main.inc.php');
diff --git a/api/http.php b/api/http.php
index 90926d1e5b531771c057ca82276711520c305b9e..2efd1a98c271d103987ffd2eda667e738e5812cd 100644
--- a/api/http.php
+++ b/api/http.php
@@ -25,6 +25,8 @@ $dispatcher = patterns('',
          ))
         );
 
+Signal::send('api', $dispatcher);
+
 # Call the respective function
 print $dispatcher->resolve($ost->get_path_info());
 ?>
diff --git a/include/class.auth.php b/include/class.auth.php
index b28d0c9876c87cc18810700d3703ab9fcbc878bc..e77fec723db46db8c56d56460b1b0068d44afad7 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -308,8 +308,32 @@ abstract class AuthenticationBackend {
     abstract static function signOut($user);
 }
 
-class RemoteAuthenticationBackend {
-    var $create_unknown_user = false;
+/**
+ * ExternalAuthenticationBackend
+ *
+ * External authentication backends are backends such as Google+ which
+ * require a redirect to a remote site and a redirect back to osTicket in
+ * order for a  user to be authenticated. For such backends, neither the
+ * username and password fields nor single sign on alone can be used to
+ * authenticate the user.
+ */
+interface ExternalAuthentication {
+
+    /**
+     * Requests the backend to render an external link box. When the user
+     * clicks this box, the backend will be prompted to redirect the user to
+     * the remote site for authentication there.
+     */
+    function renderExternalLink();
+
+    /**
+     * Function: triggerAuth
+     *
+     * Called when a user clicks the button rendered in the
+     * ::renderExternalLink() function. This method should initiate the
+     * remote authentication mechanism.
+     */
+    function triggerAuth();
 }
 
 abstract class StaffAuthenticationBackend  extends AuthenticationBackend {
@@ -454,6 +478,50 @@ abstract class StaffAuthenticationBackend  extends AuthenticationBackend {
     }
 }
 
+abstract class ExternalStaffAuthenticationBackend
+        extends StaffAuthenticationBackend
+        implements ExternalAuthentication {
+
+    static $fa_icon = "signin";
+    static $sign_in_image_url = false;
+    static $service_name = "External";
+
+    function renderExternalLink() { ?>
+        <a class="external-sign-in" title="Sign in with <?php echo static::$service_name; ?>"
+                href="login.php?do=ext&amp;bk=<?php echo urlencode(static::$id); ?>">
+<?php if (static::$sign_in_image_url) { ?>
+        <img class="sign-in-image" src="<?php echo static::$sign_in_image_url;
+            ?>" alt="Sign in with <?php echo static::$service_name; ?>"/>
+<?php } else { ?>
+            <div class="external-auth-box">
+            <span class="external-auth-icon">
+                <i class="icon-<?php echo static::$fa_icon; ?> icon-large icon-fixed-with"></i>
+            </span>
+            <span class="external-auth-name">
+                Sign in with <?php echo static::$service_name; ?>
+            </span>
+            </div>
+<?php } ?>
+        </a><?php
+    }
+
+    function triggerAuth() {
+        $_SESSION['ext:bk:class'] = get_class($this);
+    }
+}
+Signal::connect('api', function($dispatcher) {
+    $dispatcher->append(
+        url('^/auth/ext$', function() {
+            if ($class = $_SESSION['ext:bk:class']) {
+                $bk = StaffAuthenticationBackend::getBackend($class::$id)
+                    ?: UserAuthenticationBackend::getBackend($class::$id);
+                if ($bk instanceof ExternalAuthentication)
+                    $bk->triggerAuth();
+            }
+        })
+    );
+});
+
 abstract class UserAuthenticationBackend  extends AuthenticationBackend {
 
     static private $_registry = array();
@@ -580,6 +648,38 @@ abstract class UserAuthenticationBackend  extends AuthenticationBackend {
     }
 }
 
+abstract class ExternalUserAuthenticationBackend
+        extends UserAuthenticationBackend
+        implements ExternalAuthentication {
+
+    static $fa_icon = "signin";
+    static $sign_in_image_url = false;
+    static $service_name = "External";
+
+    function renderExternalLink() { ?>
+        <a class="external-sign-in" title="Sign in with <?php echo static::$service_name; ?>"
+                href="login.php?do=ext&amp;bk=<?php echo urlencode(static::$id); ?>">
+<?php if (static::$sign_in_image_url) { ?>
+        <img class="sign-in-image" src="<?php echo static::$sign_in_image_url;
+            ?>" alt="Sign in with <?php echo static::$service_name; ?>"/>
+<?php } else { ?>
+            <div class="external-auth-box">
+            <span class="external-auth-icon">
+                <i class="icon-<?php echo static::$fa_icon; ?> icon-large icon-fixed-with"></i>
+            </span>
+            <span class="external-auth-name">
+                Sign in with <?php echo static::$service_name; ?>
+            </span>
+            </div>
+<?php } ?>
+        </a><?php
+    }
+
+    function triggerAuth() {
+        $_SESSION['ext:bk:class'] = get_class($this);
+    }
+}
+
 /**
  * This will be an exception in later versions of PHP
  */
diff --git a/include/class.ostsession.php b/include/class.ostsession.php
index beb344f9f3734f5e286e9d2e4aff0060d6406cb2..dc53af14ef11f7eda69ae94fbb78db6e1cfafd93 100644
--- a/include/class.ostsession.php
+++ b/include/class.ostsession.php
@@ -35,9 +35,6 @@ class osTicketSession {
         if (OsticketConfig::getDBVersion())
             return session_start();
 
-        elseif (defined('DISABLE_SESSION'))
-            return;
-
         # Cookies
         // Avoid setting a cookie domain without a dot, thanks
         // http://stackoverflow.com/a/1188145
@@ -80,6 +77,7 @@ class osTicketSession {
     }
 
     function read($id){
+        $this->isnew = true;
         if (!$this->data || $this->id != $id) {
             $sql='SELECT session_data FROM '.SESSION_TABLE
                 .' WHERE session_id='.db_input($id)
@@ -91,6 +89,7 @@ class osTicketSession {
             $this->id = $id;
         }
         $this->data_hash = md5($id.$this->data);
+        $this->isnew = false;
         return $this->data;
     }
 
@@ -100,6 +99,9 @@ class osTicketSession {
         if (md5($id.$data) == $this->data_hash)
             return;
 
+        elseif (defined('DISABLE_SESSION') && $this->isnew)
+            return;
+
         $ttl = ($this && get_class($this) == 'osTicketSession')
             ? $this->getTTL() : SESSION_TTL;