diff --git a/tests/tfa.test b/tests/tfa.test
index 9997242..d8a1468 100644
--- a/tests/tfa.test
+++ b/tests/tfa.test
@@ -241,35 +241,6 @@ class TfaTestCase extends DrupalWebTestCase {
     $this->assertNoFieldById('edit-code', '', 'The send code input does not appear');
   }
 
-  public function testReadyAndRequired() {
-    variable_set('tfa_validate_plugin', 'tfa_test_send');
-    $account = $this->web_user;
-
-    // Disable ready.
-    variable_set('tfa_test_is_ready', FALSE);
-
-    $edit = array(
-      'name' => $account->name,
-      'pass' => $account->pass_raw,
-    );
-    $this->drupalPost('user/login', $edit, 'Log in');
-    $this->assertLink('Log out', 0, 'Authenticated');
-
-    $this->drupalLogout();
-
-    // Swap plugin.
-    variable_set('tfa_validate_plugin', 'tfa_test_totp');
-    // New account with the require TFA permission.
-    $account = $this->drupalCreateUser(array('access content', 'require tfa'));
-    $edit = array(
-      'name' => $account->name,
-      'pass' => $account->pass_raw,
-    );
-    $this->drupalPost('user/login', $edit, 'Log in');
-    $this->assertNoLink('Log out', 'Not authenticated');
-    $this->assertText($this->uiStrings('required'), 'Required text shows');
-  }
-
   /**
    * Test tfa_context_alter.
    */
@@ -369,8 +340,6 @@ class TfaTestCase extends DrupalWebTestCase {
         return 'You have reached the threshold for incorrect code entry attempts.';
       case 'flood-begin':
         return 'You have reached the threshold for TFA attempts.';
-      case 'required':
-        return 'Login disallowed. You are required to setup two-factor authentication. Please contact a site administrator.';
     }
   }
 }
diff --git a/tfa.api.php b/tfa.api.php
index b81c6c1..66424e9 100644
--- a/tfa.api.php
+++ b/tfa.api.php
@@ -153,3 +153,20 @@ function my_tfa_setup_form_submit($form, &$form_state) {
 function hook_tfa_flood_hit($context = array()) {
 
 }
+
+/**
+ * Whether log in should be halted because TFA is not setup for the account.
+ *
+ * Implement this hook to decide if authentication should be denied under the
+ * conditions of the account not having TFA set up. TFA module will have invoked
+ * 'ready' methods on enabled plugins already.
+ *
+ * @param object $account
+ *   User account.
+ *
+ * @return bool
+ *   FALSE to disallow login or TRUE to allow it without undergoing TFA.
+ */
+function hook_tfa_require($account) {
+
+}
diff --git a/tfa.module b/tfa.module
index c202da0..3f6c5b2 100644
--- a/tfa.module
+++ b/tfa.module
@@ -44,10 +44,6 @@ function tfa_entry_access($account, $url_hash) {
  */
 function tfa_permission() {
   return array(
-    'require tfa' => array(
-      'title' => t('Require TFA process'),
-      'description' => t('Require two-factor to authenticate. Note: users without TFA setup will be unable to log in.'),
-    ),
     'admin tfa settings' => array(
       'title' => t('Administer TFA'),
       'description' => t('Configure two-factor authentication settings.'),
@@ -262,14 +258,30 @@ function tfa_login_submit($form, &$form_state) {
   // Similar to tfa_user_login() but not required to force user logout.
 
   $account = isset($form_state['uid']) ? user_load($form_state['uid']) : user_load_by_name($form_state['values']['name']);
-  $tfa = tfa_get_process($account);
-
-  if (user_access('require tfa', $account) && !tfa_login_complete($account) && !$tfa->ready()) {
-    drupal_set_message(t('Login disallowed. You are required to setup two-factor authentication. Please contact a site administrator.'), 'error');
-    $form_state['redirect'] = 'user';
+  // Return early if user has succesfully gone through TFA process or if
+  // a login plugin specifically allows it.
+  if (tfa_login_allowed($account)) {
+    // Authentication can continue so invoke user_login_submit().
+    user_login_submit($form, $form_state);
+    return;
   }
-  elseif (!tfa_login_complete($account) && $tfa->ready() && !tfa_login_allowed($account)) {
 
+  $tfa = tfa_get_process($account);
+  // Check if TFA has been set up by the account.
+  if (!$tfa->ready()) {
+    // Allow other modules to act on login when account is not set up for TFA.
+    $require_tfa = array_filter(module_invoke_all('tfa_require', $account));
+    if (!empty($require_tfa)) {
+      $form_state['redirect'] = !empty($form_state['redirect']) ? $form_state['redirect'] : 'user';
+      return;
+    }
+    else {
+      // Not required so continue with log in.
+      user_login_submit($form, $form_state);
+      return;
+    }
+  }
+  else {
     // Restart flood levels, session context, and TFA process.
     $identifier = variable_get('user_failed_login_identifier_uid_only', FALSE) ? $account->uid : $account->uid . '-' . ip_address();
     flood_clear_event('tfa_user', $identifier);
@@ -297,34 +309,22 @@ function tfa_login_submit($form, &$form_state) {
       array('query' => $query),
     );
   }
-  else {
-    // Authentication can continue so invoke user_login_submit().
-    user_login_submit($form, $form_state);
-  }
 }
 
 /**
- * Check if TFA process has completed so authentication should not be stopped.
+ * Check TFA plugins if login should be interrupted for authenticating account.
+ *
+ * @param object $account
+ *   User account
  *
- * @param $account User account
  * @return bool
  */
-function tfa_login_complete($account) {
+function tfa_login_allowed($account) {
   // TFA master login allowed switch is set by tfa_login().
   if (isset($_SESSION['tfa'][$account->uid]['login']) && $_SESSION['tfa'][$account->uid]['login'] === TRUE) {
     return TRUE;
   }
-  return FALSE;
-}
-
-/**
- * Check TFA plugins if login should be interrupted for authenticating account.
- *
- * @param $account User account
- * @return bool
- */
-function tfa_login_allowed($account) {
-  // Check if login plugins will allow login.
+  // Else check if login plugins will specifically allow login.
   $tfa = tfa_get_process($account);
   return $tfa->loginAllowed() === TRUE;
 }
@@ -336,14 +336,23 @@ function tfa_user_login(&$edit, $account) {
   if (!variable_get('tfa_enabled', 0)) {
     return;
   }
+  // Return early if user has succesfully gone through TFA process or if
+  // a login plugin specifically allows it.
+  if (tfa_login_allowed($account)) {
+    return;
+  }
 
   $tfa = tfa_get_process($account);
-  if (user_access('require tfa', $account) && !tfa_login_complete($account) && !$tfa->ready()) {
-    tfa_logout();
-    drupal_set_message(t('Login disallowed. You are required to setup two-factor authentication. Please contact a site administrator.'), 'error');
-    drupal_goto('user');
+  // Check if TFA has been set up by the account.
+  if (!$tfa->ready()) {
+    // Allow other modules to act on login when account is not set up for TFA.
+    $require_tfa = array_filter(module_invoke_all('tfa_require', $account));
+    if (!empty($require_tfa)) {
+      tfa_logout();
+      drupal_goto('user');
+    }
   }
-  elseif (!tfa_login_complete($account) && $tfa->ready() && !tfa_login_allowed($account)) {
+  else {
     // User has been authenticated so force logout and redirect to TFA form.
     tfa_logout();
     // Restart flood levels, session context, and TFA process.
