diff --git a/include/class.auth.php b/include/class.auth.php
index 09708971fe24750cb1c8db3fd69215554f345381..ff8b54466e493ebb40ae48723c3668fd9a280d15 100644
--- a/include/class.auth.php
+++ b/include/class.auth.php
@@ -100,6 +100,18 @@ abstract class AuthenticationBackend {
             return $backends[$id];
     }
 
+    /*
+     * Allow the backend to do login audit depending on the result
+     * This is mainly used to track failed login attempts
+     */
+    static function authAudit($result, $credentials=null) {
+
+        if (!$result) return;
+
+        foreach (static::allRegistered() as $bk)
+            $bk->audit($result, $credentials);
+    }
+
     static function process($username, $password=null, &$errors) {
 
         if (!$username)
@@ -117,22 +129,32 @@ abstract class AuthenticationBackend {
             // authentication so that extensions like lockouts and audits
             // can be supported.
             $result = $bk->authenticate($username, $password);
-
             if ($result instanceof AuthenticatedUser
                     && ($bk->login($result, $bk)))
                 return $result;
-            // TODO: Handle permission denied, for instance
             elseif ($result instanceof AccessDenied) {
-                $errors['err'] = $result->reason;
                 break;
             }
         }
 
-        $info = array('username'=>$username, 'password'=>$password);
+        if (!$result)
+            $result = new  AccessDenied('Access denied');
+
+        if ($result && $result instanceof AccessDenied)
+            $errors['err'] = $result->reason;
+
+        $info = array('username' => $username, 'password' => $password);
         Signal::send('auth.login.failed', null, $info);
+        self::authAudit($result, $info);
     }
 
-    function processSignOn(&$errors) {
+    /*
+     *  Attempt to process non-interactive sign-on e.g  HTTP-Passthrough
+     *
+     * $forcedAuth - indicate if authentication is required.
+     *
+     */
+    function processSignOn(&$errors, $forcedAuth=true) {
 
         foreach (static::allRegistered() as $bk) {
             // All backends are queried here, even if they don't support
@@ -146,12 +168,18 @@ abstract class AuthenticationBackend {
 
                 return $result;
             }
-            // TODO: Handle permission denied, for instance
             elseif ($result instanceof AccessDenied) {
-                $errors['err'] = $result->reason;
                 break;
             }
         }
+
+        if (!$result && $forcedAuth)
+            $result = new  AccessDenied('Unknown user');
+
+        if ($result && $result instanceof AccessDenied)
+            $errors['err'] = $result->reason;
+
+        self::authAudit($result);
     }
 
     static function searchUsers($query) {
@@ -202,6 +230,10 @@ abstract class AuthenticationBackend {
         return null;
     }
 
+    protected function audit($result, $credentials) {
+        return null;
+    }
+
     abstract function authenticate($username, $password);
     abstract function login($user, $bk);
     abstract static function getUser(); //Validates  authenticated users.
@@ -465,9 +497,6 @@ abstract class UserAuthenticationBackend  extends AuthenticationBackend {
  * This will be an exception in later versions of PHP
  */
 class AccessDenied {
-    function AccessDenied() {
-        call_user_func_array(array($this, '__construct'), func_get_args());
-    }
     function __construct($reason) {
         $this->reason = $reason;
     }
@@ -480,11 +509,11 @@ class AccessDenied {
 abstract class AuthStrikeBackend extends AuthenticationBackend {
 
     function authenticate($username, $password=null) {
-        return static::authStrike($username, $password);
+        return static::authTimeout();
     }
 
     function signOn() {
-        return static::authStrike('Unknown');
+        return static::authTimeout();
     }
 
     static function signOut($user) {
@@ -512,7 +541,17 @@ abstract class AuthStrikeBackend extends AuthenticationBackend {
         return null;
     }
 
-    abstract function  authStrike($username, $password=null);
+    //Provides audit facility for logins attempts
+    function audit($result, $credentials) {
+
+        //Count failed login attempts as a strike.
+        if ($result instanceof AccessDenied)
+            return static::authStrike($credentials);
+
+    }
+
+    abstract function authStrike($credentials);
+    abstract function authTimeout();
 }
 
 /*
@@ -520,24 +559,36 @@ abstract class AuthStrikeBackend extends AuthenticationBackend {
  */
 class StaffAuthStrikeBackend extends  AuthStrikeBackend {
 
-    function authstrike($username, $password=null) {
+    function authTimeout() {
         global $ost;
 
         $cfg = $ost->getConfig();
 
         $authsession = &$_SESSION['_auth']['staff'];
+        if (!$authsession['laststrike'])
+            return;
 
-        if($authsession['laststrike']) {
-            if((time()-$authsession['laststrike'])<$cfg->getStaffLoginTimeout()) {
-                $authsession['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.
-                $authsession['laststrike']=null;
-                $authsession['strikes']=0;
-            }
+        //Veto login due to excessive login attempts.
+        if((time()-$authsession['laststrike'])<$cfg->getStaffLoginTimeout()) {
+            $authsession['laststrike'] = time(); //reset timer.
+            return new AccessDenied('Max. failed login attempts reached');
         }
 
+        //Timeout is over.
+        //Reset the counter for next round of attempts after the timeout.
+        $authsession['laststrike']=null;
+        $authsession['strikes']=0;
+    }
+
+    function authstrike($credentials) {
+        global $ost;
+
+        $cfg = $ost->getConfig();
+
+        $authsession = &$_SESSION['_auth']['staff'];
+
+        $username = $credentials['username'];
+
         $authsession['strikes']+=1;
         if($authsession['strikes']>$cfg->getStaffMaxLogins()) {
             $authsession['laststrike']=time();
@@ -567,25 +618,37 @@ StaffAuthenticationBackend::register('StaffAuthStrikeBackend');
  */
 class UserAuthStrikeBackend extends  AuthStrikeBackend {
 
-    function authstrike($username, $password=null) {
+    function authTimeout() {
         global $ost;
 
         $cfg = $ost->getConfig();
 
         $authsession = &$_SESSION['_auth']['user'];
+        if (!$authsession['laststrike'])
+            return;
 
-        //Check time for last max failed login attempt strike.
-        if($authsession['laststrike']) {
-            if((time()-$authsession['laststrike'])<$cfg->getClientLoginTimeout()) {
-                $authsession['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.
-                $authsession['laststrike'] = null;
-                $authsession['strikes'] = 0;
-            }
+        //Veto login due to excessive login attempts.
+        if ((time()-$authsession['laststrike']) < $cfg->getStaffLoginTimeout()) {
+            $authsession['laststrike'] = time(); //reset timer.
+            return new AccessDenied("You've reached maximum failed login attempts allowed.");
         }
 
+        //Timeout is over.
+        //Reset the counter for next round of attempts after the timeout.
+        $authsession['laststrike']=null;
+        $authsession['strikes']=0;
+    }
+
+    function authstrike($credentials) {
+        global $ost;
+
+        $cfg = $ost->getConfig();
+
+        $authsession = &$_SESSION['_auth']['user'];
+
+        $username = $credentials['username'];
+        $password = $credentials['password'];
+
         $authsession['strikes']+=1;
         if($authsession['strikes']>$cfg->getClientMaxLogins()) {
             $authsession['laststrike'] = time();
diff --git a/scp/login.php b/scp/login.php
index 840716c65deda81e7b87026450ea3bfd6fd51d93..211bb70989f8fbe002fded97c9e59fa873b81ab1 100644
--- a/scp/login.php
+++ b/scp/login.php
@@ -37,7 +37,7 @@ if($_POST) {
 }
 // Consider single sign-on authentication backends
 else if (!$thisstaff || !($thisstaff->getId() || $thisstaff->isValid())) {
-    if (($user = StaffAuthenticationBackend::processSignOn($errors))
+    if (($user = StaffAuthenticationBackend::processSignOn($errors, false))
             && ($user instanceof StaffSession))
        @header("Location: $dest");
 }