diff --git a/core/modules/basic_auth/basic_auth.services.yml b/core/modules/basic_auth/basic_auth.services.yml
index 4c7a449..a0d4368 100644
--- a/core/modules/basic_auth/basic_auth.services.yml
+++ b/core/modules/basic_auth/basic_auth.services.yml
@@ -1,6 +1,6 @@
 services:
   authentication.basic_auth:
     class: Drupal\basic_auth\Authentication\Provider\BasicAuth
-    arguments: ['@config.factory', '@user.auth']
+    arguments: ['@config.factory', '@user.auth', '@flood', '@entity.manager']
     tags:
       - { name: authentication_provider, priority: 100 }
diff --git a/core/modules/basic_auth/config/basic_auth.flood.yml b/core/modules/basic_auth/config/basic_auth.flood.yml
new file mode 100644
index 0000000..9a16846
--- /dev/null
+++ b/core/modules/basic_auth/config/basic_auth.flood.yml
@@ -0,0 +1,5 @@
+uid_only: false
+ip_limit: 50
+ip_window: 3600
+user_limit: 5
+user_window: 21600
diff --git a/core/modules/basic_auth/config/schema/basic_auth.schema.yml b/core/modules/basic_auth/config/schema/basic_auth.schema.yml
new file mode 100644
index 0000000..40a515c
--- /dev/null
+++ b/core/modules/basic_auth/config/schema/basic_auth.schema.yml
@@ -0,0 +1,21 @@
+# Schema for the configuration files of the HTTP Basic Authentication module.
+
+basic_auth.flood:
+  type: mapping
+  label: 'Basic Auth flood settings'
+  mapping:
+    uid_only:
+      type: boolean
+      label: 'User ID only'
+    ip_limit:
+      type: integer
+      label: 'IP limit'
+    ip_window:
+      type: integer
+      label: 'IP limit duration'
+    user_limit:
+      type: integer
+      label: 'User limit'
+    user_window:
+      type: integer
+      label: 'User limit duration'
diff --git a/core/modules/basic_auth/lib/Drupal/basic_auth/Authentication/Provider/BasicAuth.php b/core/modules/basic_auth/lib/Drupal/basic_auth/Authentication/Provider/BasicAuth.php
index 579d8a0..4e50304 100644
--- a/core/modules/basic_auth/lib/Drupal/basic_auth/Authentication/Provider/BasicAuth.php
+++ b/core/modules/basic_auth/lib/Drupal/basic_auth/Authentication/Provider/BasicAuth.php
@@ -9,9 +9,11 @@
 
 use \Drupal\Component\Utility\String;
 use Drupal\Core\Authentication\AuthenticationProviderInterface;
-use Drupal\Core\Config\Config;
 use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Flood\FloodInterface;
 use Drupal\user\UserAuthInterface;
+use Drupal\user\UserStorageControllerInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
 use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
@@ -37,14 +39,36 @@ class BasicAuth implements AuthenticationProviderInterface {
   protected $userAuth;
 
   /**
+   * The flood service.
+   *
+   * @var \Drupal\Core\Flood\FloodInterface
+   */
+  protected $flood;
+
+  /**
+   * The user storage controller.
+   *
+   * @var \Drupal\user\UserStorageControllerInterface
+   */
+  protected $userStorage;
+
+  /**
    * Constructs a HTTP basic authentication provider object.
    *
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The config factory.
+   * @param \Drupal\user\UserAuthInterface $user_auth
+   *   The user authentication service.
+   * @param \Drupal\Core\Flood\FloodInterface $flood
+   *   The flood service.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager service.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, UserAuthInterface $user_auth) {
+  public function __construct(ConfigFactoryInterface $config_factory, UserAuthInterface $user_auth, FloodInterface $flood, EntityManagerInterface $entity_manager) {
     $this->configFactory = $config_factory;
     $this->userAuth = $user_auth;
+    $this->flood = $flood;
+    $this->userStorage = $entity_manager->getStorageController('user');
   }
 
   /**
@@ -60,12 +84,50 @@ public function applies(Request $request) {
    * {@inheritdoc}
    */
   public function authenticate(Request $request) {
+    $flood_config = $this->configFactory->get('basic_auth.flood');
     $username = $request->headers->get('PHP_AUTH_USER');
     $password = $request->headers->get('PHP_AUTH_PW');
-    $uid = $this->userAuth->authenticate($username, $password);
-    if ($uid) {
-      return user_load($uid);
+    // Flood protection: this is very similar to the user login form code.
+    // @see \Drupal\user\Form\UserLoginForm::validateAuthentication()
+    // Do not allow any login from the current user's IP if the limit has been
+    // reached. Default is 50 failed attempts allowed in one hour. This is
+    // independent of the per-user limit to catch attempts from one IP to log
+    // in to many different user accounts.  We have a reasonably high limit
+    // since there may be only one apparent IP for all users at an institution.
+    if ($this->flood->isAllowed('basic_auth.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
+      $accounts = $this->userStorage->loadByProperties(array('name' => $username, 'status' => 1));
+      $account = reset($accounts);
+      if ($account) {
+        if ($flood_config->get('uid_only')) {
+          // Register flood events based on the uid only, so they apply for any
+          // IP address. This is the most secure option.
+          $identifier = $account->id();
+        }
+        else {
+          // The default identifier is a combination of uid and IP address. This
+          // is less secure but more resistant to denial-of-service attacks that
+          // could lock out all users with public user names.
+          $identifier = $account->id() . '-' . $request->getClientIP();
+        }
+        // Don't allow login if the limit for this user has been reached.
+        // Default is to allow 5 failed attempts every 6 hours.
+        if ($this->flood->isAllowed('basic_auth.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
+          $uid = $this->userAuth->authenticate($username, $password);
+          if ($uid) {
+            $this->flood->clear('basic_auth.failed_login_user', $identifier);
+            $account = $this->userStorage->load($uid);
+            $cached_user = $account;
+            return $account;
+          }
+          else {
+            // Register a per-user failed login event.
+            $this->flood->register('basic_auth.failed_login_user', $flood_config->get('user_window'), $identifier);
+          }
+        }
+      }
     }
+    // Always register an IP-based failed login event.
+    $this->flood->register('basic_auth.failed_login_ip', $flood_config->get('ip_window'));
     return NULL;
   }
 
@@ -92,4 +154,5 @@ public function handleException(GetResponseForExceptionEvent $event) {
     }
     return FALSE;
   }
+
 }
diff --git a/core/modules/basic_auth/lib/Drupal/basic_auth/Tests/Authentication/BasicAuthTest.php b/core/modules/basic_auth/lib/Drupal/basic_auth/Tests/Authentication/BasicAuthTest.php
index b8f5805..21c9a8b 100644
--- a/core/modules/basic_auth/lib/Drupal/basic_auth/Tests/Authentication/BasicAuthTest.php
+++ b/core/modules/basic_auth/lib/Drupal/basic_auth/Tests/Authentication/BasicAuthTest.php
@@ -7,9 +7,7 @@
 
 namespace Drupal\basic_auth\Tests\Authentication;
 
-use Drupal\Core\Authentication\Provider\BasicAuth;
 use Drupal\simpletest\WebTestBase;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Test for http basic authentication.
@@ -62,6 +60,67 @@ public function testBasicAuth() {
   }
 
   /**
+   * Test the global login flood control.
+   */
+  function testGlobalLoginFloodControl() {
+    \Drupal::config('basic_auth.flood')
+      ->set('ip_limit', 2)
+      // Set a high per-user limit out so that it is not relevant in the test.
+      ->set('user_limit', 4000)
+      ->save();
+
+    $user = $this->drupalCreateUser(array());
+    $incorrect_user = clone $user;
+    $incorrect_user->pass_raw .= 'incorrect';
+
+    // Try 2 failed logins.
+    for ($i = 0; $i < 2; $i++) {
+      $this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
+    }
+
+    // IP limit has reached to its limit. Even valid user credentials will fail.
+    $this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
+    $this->assertResponse('403', 'Access is blocked because of IP based flood prevention.');
+  }
+
+  /**
+   * Test the per-user login flood control.
+   */
+  function testPerUserLoginFloodControl() {
+    \Drupal::config('basic_auth.flood')
+      // Set a high global limit out so that it is not relevant in the test.
+      ->set('ip_limit', 4000)
+      ->set('user_limit', 2)
+      ->save();
+
+    $user = $this->drupalCreateUser(array());
+    $incorrect_user = clone $user;
+    $incorrect_user->pass_raw .= 'incorrect';
+    $user2 = $this->drupalCreateUser(array());
+
+    // Try a failed login.
+    $this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
+
+    // A successful login will reset the per-user flood control count.
+    $this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
+    $this->assertResponse('200', 'Per user flood prevention gets reset on a successful login.');
+
+    // Try 2 failed logins for a user. They will trigger flood control.
+    for ($i = 0; $i < 2; $i++) {
+      $this->basicAuthGet('router_test/test11', $incorrect_user->getUsername(), $incorrect_user->pass_raw);
+    }
+
+    // Now the user account is blocked.
+    $this->basicAuthGet('router_test/test11', $user->getUsername(), $user->pass_raw);
+    $this->assertResponse('403', 'The user account is blocked due to per user flood prevention.');
+
+    // Try one successful attempt for a different user, it should not trigger
+    // any flood control.
+    $this->basicAuthGet('router_test/test11', $user2->getUsername(), $user2->pass_raw);
+    $this->assertResponse('200', 'Per user flood prevention does not block access for other users.');
+  }
+
+  /**
    * Does HTTP basic auth request.
    *
    * We do not use \Drupal\simpletest\WebTestBase::drupalGet because we need to
@@ -93,4 +152,5 @@ protected function basicAuthGet($path, $username, $password) {
 
     return $out;
   }
+
 }
