diff --git a/include/class.auth.php b/include/class.auth.php
index 44d382f732e2c7d4e78da2ffedd5c8d299082124..7d933c771cff4cf01e70e05c5673f6ce63b0b071 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -3,14 +3,22 @@ require(INCLUDE_DIR.'class.ostsession.php');
 require(INCLUDE_DIR.'class.usersession.php');
 
 
-interface AuthenticatedUser {
+abstract class AuthenticatedUser {
+    //Authorization key returned by the backend used to authorize the user
+    private $authkey;
 
     // Get basic information
-    function getId();
-    function getUsername();
-    function setBackend($bk);
-    function getBackend();
-    function getRole();
+    abstract function getId();
+    abstract function getUsername();
+    abstract function getRole();
+
+    function setAuthKey($key) {
+        $this->authkey = $key;
+    }
+
+    function getAuthKey() {
+        return $this->authkey;
+    }
 }
 
 interface AuthDirectorySearch {
@@ -72,7 +80,11 @@ abstract class AuthenticationBackend {
     }
 
     static function getBackend($id) {
-        return static::$registry[$id];
+
+        if ($id
+                && ($backends = static::allRegistered())
+                && isset($backends[$id]))
+            return $backends[$id];
     }
 
     static function process($username, $password=null, &$errors) {
@@ -94,11 +106,8 @@ abstract class AuthenticationBackend {
             $result = $bk->authenticate($username, $password);
 
             if ($result instanceof AuthenticatedUser
-                    && (static::login($result, $bk))) {
-                $result->setBackend($bk);
-
+                    && (static::login($result, $bk)))
                 return $result;
-            }
             // TODO: Handle permission denied, for instance
             elseif ($result instanceof AccessDenied) {
                 $errors['err'] = $result->reason;
@@ -121,9 +130,8 @@ abstract class AuthenticationBackend {
             if ($result instanceof AuthenticatedUser) {
                 //Perform further Object specific checks and the actual login
                 if (!static::login($result, $bk))
-                    continue
+                    continue;
 
-                $result->setBackend($bk);
                 return $result;
             }
             // TODO: Handle permission denied, for instance
@@ -181,7 +189,7 @@ abstract class AuthenticationBackend {
     abstract function authenticate($username, $password);
     abstract function login($user, $bk);
     abstract function getAllowedBackends($userid);
-
+    abstract protected function getAuthKey($user);
 }
 
 class RemoteAuthenticationBackend {
@@ -226,32 +234,39 @@ abstract class StaffAuthenticationBackend  extends AuthenticationBackend {
         return array_filter($backends);
     }
 
-    function login($user, $bk) {
+    function login($staff, $bk) {
         global $ost;
 
-        if (!($user instanceof Staff))
+        if (!$bk || !($staff instanceof Staff))
             return false;
 
         // Ensure staff is allowed for realz to be authenticated via the backend.
-        if (!static::isBackendAllowed($user, $bk))
+        if (!static::isBackendAllowed($staff, $bk)
+            || !($authkey=$bk->getAuthKey($staff)))
             return false;
 
         //Log debug info.
         $ost->logDebug('Staff login',
-            sprintf("%s logged in [%s], via %s", $user->getUserName(),
+            sprintf("%s logged in [%s], via %s", $staff->getUserName(),
                 $_SERVER['REMOTE_ADDR'], get_class($bk))); //Debug.
 
         $sql='UPDATE '.STAFF_TABLE.' SET lastlogin=NOW() '
-            .' WHERE staff_id='.db_input($user->getId());
+            .' WHERE staff_id='.db_input($staff->getId());
         db_query($sql);
+
+        //Tag the authkey.
+        $authkey = $bk::$id.':'.$authkey;
+
         //Now set session crap and lets roll baby!
-        $_SESSION['_staff'] = array(); //clear.
-        $_SESSION['_staff']['userID'] = $user->getUserName();
+        $_SESSION['_auth']['staff'] = array(); //clear.
+        $_SESSION['_auth']['staff']['id'] = $staff->getId();
+        $_SESSION['_auth']['staff']['key'] =  $authkey;
 
-        $user->refreshSession(); //set the hash.
+        $staff->setAuthKey($authkey);
+        $staff->refreshSession(); //set the hash.
 
-        $_SESSION['TZ_OFFSET'] = $user->getTZoffset();
-        $_SESSION['TZ_DST'] = $user->observeDaylight();
+        $_SESSION['TZ_OFFSET'] = $staff->getTZoffset();
+        $_SESSION['TZ_DST'] = $staff->observeDaylight();
 
         //Regenerate session id.
         $sid = session_id(); //Current id
@@ -262,12 +277,16 @@ abstract class StaffAuthenticationBackend  extends AuthenticationBackend {
                 && $sid!=session_id())
             $session->destroy($sid);
 
-        Signal::send('auth.login.succeeded', $user);
+        Signal::send('auth.login.succeeded', $staff);
 
-        $user->cancelResetTokens();
+        $staff->cancelResetTokens();
 
         return true;
     }
+
+    protected function getAuthKey($staff) {
+        return null;
+    }
 }
 
 abstract class UserAuthenticationBackend  extends AuthenticationBackend {
@@ -290,19 +309,29 @@ abstract class UserAuthenticationBackend  extends AuthenticationBackend {
     function login($user, $bk) {
         global $ost;
 
-        if (!($user instanceof TicketUser))
+        if (!$user || !$bk
+                || !$bk::$id //Must have ID
+                || !($authkey = $bk->getAuthKey($user)))
             return false;
 
-        $_SESSION['_client'] = array(); //clear.
-        $_SESSION['_client']['userID'] = $user->getEmail(); //Email
-        //$_SESSION['_client']['key'] = $ticket->getExtId(); //Ticket ID --acts as password when used with email. See above.
-        $_SESSION['_client']['token'] = $user->getSessionToken();
+        //Tag the authkey.
+        $authkey = $bk::$id.':'.$authkey;
+        //Set the session goodies
+        $_SESSION['_auth']['user'] = array(); //clear.
+        $_SESSION['_auth']['user']['id'] = $user->getId();
+        $_SESSION['_auth']['user']['key'] = $authkey;
         $_SESSION['TZ_OFFSET'] = $ost->getConfig()->getTZoffset();
         $_SESSION['TZ_DST'] = $ost->getConfig()->observeDaylightSaving();
+
+        //The backend used decides the format of the auth key.
+        // XXX: encrypt to hide the bk??
+        $user->setAuthKey($authkey);
+
         $user->refreshSession(); //set the hash.
+
         //Log login info...
-        $msg=sprintf('%s/%s logged in [%s]',
-                $user->getEmail(), $user->getId(), $_SERVER['REMOTE_ADDR']);
+        $msg=sprintf('%s (%s) logged in [%s]',
+                $user->getUserName(), $user->getId(), $_SERVER['REMOTE_ADDR']);
         $ost->logDebug('User login', $msg);
 
         //Regenerate session ID.
@@ -314,6 +343,11 @@ abstract class UserAuthenticationBackend  extends AuthenticationBackend {
         return true;
     }
 
+
+    protected function getAuthKey($user) {
+        return null;
+    }
+
 }
 
 /**
@@ -354,6 +388,10 @@ abstract class AuthStrikeBackend extends AuthenticationBackend {
         return array();
     }
 
+    function getAuthKey($user) {
+        return null;
+    }
+
     abstract function  authStrike($username, $password=null);
 }
 
@@ -367,35 +405,35 @@ class StaffAuthStrikeBackend extends  AuthStrikeBackend {
 
         $cfg = $ost->getConfig();
 
-        if($_SESSION['_staff']['laststrike']) {
-            if((time()-$_SESSION['_staff']['laststrike'])<$cfg->getStaffLoginTimeout()) {
-                $_SESSION['_staff']['laststrike'] = time(); //reset timer.
+        if($_SESSION['_auth']['staff']['laststrike']) {
+            if((time()-$_SESSION['_auth']['staff']['laststrike'])<$cfg->getStaffLoginTimeout()) {
+                $_SESSION['_auth']['staff']['laststrike'] = time(); //reset timer.
                 return new AccessDenied('Max. failed login attempts reached');
             } else { //Timeout is over.
                 //Reset the counter for next round of attempts after the timeout.
-                $_SESSION['_staff']['laststrike']=null;
-                $_SESSION['_staff']['strikes']=0;
+                $_SESSION['_auth']['staff']['laststrike']=null;
+                $_SESSION['_auth']['staff']['strikes']=0;
             }
         }
 
-        $_SESSION['_staff']['strikes']+=1;
-        if($_SESSION['_staff']['strikes']>$cfg->getStaffMaxLogins()) {
-            $_SESSION['_staff']['laststrike']=time();
+        $_SESSION['_auth']['staff']['strikes']+=1;
+        if($_SESSION['_auth']['staff']['strikes']>$cfg->getStaffMaxLogins()) {
+            $_SESSION['_auth']['staff']['laststrike']=time();
             $alert='Excessive login attempts by a staff member?'."\n".
                    'Username: '.$username."\n"
                    .'IP: '.$_SERVER['REMOTE_ADDR']."\n"
                    .'TIME: '.date('M j, Y, g:i a T')."\n\n"
-                   .'Attempts #'.$_SESSION['_staff']['strikes']."\n"
+                   .'Attempts #'.$_SESSION['_auth']['staff']['strikes']."\n"
                    .'Timeout: '.($cfg->getStaffLoginTimeout()/60)." minutes \n\n";
             $ost->logWarning('Excessive login attempts ('.$username.')', $alert,
                     $cfg->alertONLoginError());
             return new AccessDenied('Forgot your login info? Contact Admin.');
         //Log every other failed login attempt as a warning.
-        } elseif($_SESSION['_staff']['strikes']%2==0) {
+        } elseif($_SESSION['_auth']['staff']['strikes']%2==0) {
             $alert='Username: '.$username."\n"
                     .'IP: '.$_SERVER['REMOTE_ADDR']."\n"
                     .'TIME: '.date('M j, Y, g:i a T')."\n\n"
-                    .'Attempts #'.$_SESSION['_staff']['strikes'];
+                    .'Attempts #'.$_SESSION['_auth']['staff']['strikes'];
             $ost->logWarning('Failed staff login attempt ('.$username.')', $alert, false);
         }
     }
@@ -412,30 +450,31 @@ class UserAuthStrikeBackend extends  AuthStrikeBackend {
 
         $cfg = $ost->getConfig();
 
+        $_SESSION['_auth']['user'] = array();
         //Check time for last max failed login attempt strike.
-        if($_SESSION['_client']['laststrike']) {
-            if((time()-$_SESSION['_client']['laststrike'])<$cfg->getClientLoginTimeout()) {
-                $_SESSION['_client']['laststrike'] = time(); //renew the strike.
+        if($_SESSION['_auth']['user']['laststrike']) {
+            if((time()-$_SESSION['_auth']['user']['laststrike'])<$cfg->getClientLoginTimeout()) {
+                $_SESSION['_auth']['user']['laststrike'] = time(); //renew the strike.
                 return new AccessDenied('You\'ve reached maximum failed login attempts allowed.');
             } else { //Timeout is over.
                 //Reset the counter for next round of attempts after the timeout.
-                $_SESSION['_client']['laststrike'] = null;
-                $_SESSION['_client']['strikes'] = 0;
+                $_SESSION['_auth']['user']['laststrike'] = null;
+                $_SESSION['_auth']['user']['strikes'] = 0;
             }
         }
 
-        $_SESSION['_client']['strikes']+=1;
-        if($_SESSION['_client']['strikes']>$cfg->getClientMaxLogins()) {
-            $_SESSION['_client']['laststrike'] = time();
+        $_SESSION['_auth']['user']['strikes']+=1;
+        if($_SESSION['_auth']['user']['strikes']>$cfg->getClientMaxLogins()) {
+            $_SESSION['_auth']['user']['laststrike'] = time();
             $alert='Excessive login attempts by a user.'."\n".
                     'Login: '.$username.': '.$password."\n".
                     'IP: '.$_SERVER['REMOTE_ADDR']."\n".'Time:'.date('M j, Y, g:i a T')."\n\n".
-                    'Attempts #'.$_SESSION['_client']['strikes'];
+                    'Attempts #'.$_SESSION['_auth']['user']['strikes'];
             $ost->logError('Excessive login attempts (user)', $alert, ($cfg->alertONLoginError()));
             return new AccessDenied('Access Denied');
-        } elseif($_SESSION['_client']['strikes']%2==0) { //Log every other failed login attempt as a warning.
+        } elseif($_SESSION['_auth']['user']['strikes']%2==0) { //Log every other failed login attempt as a warning.
             $alert='Login: '.$username.': '.$password."\n".'IP: '.$_SERVER['REMOTE_ADDR'].
-                   "\n".'TIME: '.date('M j, Y, g:i a T')."\n\n".'Attempts #'.$_SESSION['_client']['strikes'];
+                   "\n".'TIME: '.date('M j, Y, g:i a T')."\n\n".'Attempts #'.$_SESSION['_auth']['user']['strikes'];
             $ost->logWarning('Failed login attempt (user)', $alert);
         }
 
@@ -462,6 +501,15 @@ class osTicketAuthentication extends StaffAuthenticationBackend {
             return $user;
         }
     }
+
+    protected function getAuthKey($staff) {
+
+        if(!($staff instanceof Staff))
+            return null;
+
+        return $staff->getUsername(); //FIXME:
+    }
+
 }
 StaffAuthenticationBackend::register(osTicketAuthentication);
 
@@ -470,11 +518,41 @@ class AuthTokenAuthentication extends UserAuthenticationBackend {
     static $id = "authtoken";
 
 
+
     function signOn() {
 
-        if ($_GET['auth'] && ($user=self::__authtoken($_GET['auth'])))
-            return $user;
+        $user = null;
+        if ($_GET['auth'])
+            $user = self::__authtoken($_GET['auth']);
+        // Support old ticket based tokens.
+        elseif ($_GET['t'] && $_GET['e'] && $_GET['a']) {
+            if (($ticket = Ticket::lookupByExtId($_GET['t'], $_GET['e']))
+                    // Using old ticket auth code algo - hardcoded here because it
+                    // will be removed in ticket class in the upcoming rewrite
+                    && !strcasecmp($_GET['a'], md5($ticket->getId() .  $_GET['e'] . SECRET_SALT))
+                    && ($client = $ticket->getClient()))
+                $user = new ClientSession($client);
+        }
+
+        return $user;
+    }
+
+    protected function getAuthKey($user) {
+
+        if (!$this->supportsAuthentication()
+                || !$user
+                || !($user instanceof EndUser))
+            return null;
+
+        //Generate authkey based the type of ticket user
+        // It's required to validate users going forward.
+        $authkey = sprintf('%s%dt%dh%s',  //XXX: Placeholder
+                    $user->isOwner() ? 'o':'c',
+                    $user->getId(),
+                    $user->getTicketID(),
+                    md5($user->getUsername().$this->id));
 
+        return $authkey;
     }
 
     static private function __authtoken($token) {
@@ -482,7 +560,7 @@ class AuthTokenAuthentication extends UserAuthenticationBackend {
         switch ($token[0]) {
             case 'c': //Collaborator c+[token]
                 if (($c = Collaborator::lookupByAuthToken($token)))
-                    return new TicketUser($c); //Decorator
+                    return new ClientSession($c); //Decorator
                 break;
             case 'o': //Ticket owner  o+[token]
                 break;
diff --git a/include/class.client.php b/include/class.client.php
index 184d11f81cb4037be88b2bc46d4d451443c5ccee..b6f9779fb7f96301b2a6e426956a7c357cba6f0e 100644
--- a/include/class.client.php
+++ b/include/class.client.php
@@ -247,9 +247,8 @@ class Client {
  *
  */
 
-class  TicketUser implements AuthenticatedUser {
+class  EndUser extends AuthenticatedUser {
 
-    protected $backend;
     protected $user;
 
     function __construct($user) {
@@ -261,8 +260,9 @@ class  TicketUser implements AuthenticatedUser {
      */
     function __call($name, $args) {
 
+
         if(!$this->user
-                || !is_callable($this->user, $name))
+                || !is_callable(array($this->user, $name)))
             return false;
 
         return  $args
@@ -282,14 +282,6 @@ class  TicketUser implements AuthenticatedUser {
         return  ($this->user && $this->user instanceof Client);
     }
 
-    function setBackend($bk) {
-        $this->backend = $bk;
-    }
-
-    function getBackend() {
-        return $this->backend;
-    }
-
     function getUserName() {
         //XXX: Revisit when real usernames are introduced  or when email
         // requirement is removed.
diff --git a/include/class.staff.php b/include/class.staff.php
index cc64d80ffc3fe9b88087f22344cf17e8d6170397..73a2c963f26de91c499f59f99258ef93c7d3d330 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -22,7 +22,7 @@ include_once(INCLUDE_DIR.'class.passwd.php');
 include_once(INCLUDE_DIR.'class.user.php');
 include_once(INCLUDE_DIR.'class.auth.php');
 
-class Staff implements AuthenticatedUser {
+class Staff extends AuthenticatedUser {
 
     var $ht;
     var $id;
@@ -97,14 +97,6 @@ class Staff implements AuthenticatedUser {
 
     // AuthenticatedUser implementation...
     // TODO: Move to an abstract class that extends Staff
-    function setBackend($bk) {
-
-    }
-
-    function getBackend() {
-
-    }
-
     function getRole() {
         return 'staff';
     }