diff --git a/core/modules/user/config/user.flood.yml b/core/modules/user/config/user.flood.yml
new file mode 100644
index 0000000..f24e3d1
--- /dev/null
+++ b/core/modules/user/config/user.flood.yml
@@ -0,0 +1,5 @@
+identifier_uid_only: false
+ip_limit: 50
+ip_window: 3600
+user_limit: 5
+user_window: 21600
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserLoginTest.php b/core/modules/user/lib/Drupal/user/Tests/UserLoginTest.php
index b5e8882..d82f5c0 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserLoginTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserLoginTest.php
@@ -25,10 +25,11 @@ class UserLoginTest extends WebTestBase {
    * Test the global login flood control.
    */
   function testGlobalLoginFloodControl() {
+    $flood_config = config('user.flood');
     // Set the global login limit.
-    variable_set('user_failed_login_ip_limit', 10);
+    $flood_config->set('ip_limit', 10);
     // Set a high per-user limit out so that it is not relevant in the test.
-    variable_set('user_failed_login_user_limit', 4000);
+    $flood_config->set('user_limit', 4000);
 
     $user1 = $this->drupalCreateUser(array());
     $incorrect_user1 = clone $user1;
@@ -61,10 +62,11 @@ class UserLoginTest extends WebTestBase {
    * Test the per-user login flood control.
    */
   function testPerUserLoginFloodControl() {
+    $flood_config = config('user.flood');
     // Set a high global limit out so that it is not relevant in the test.
-    variable_set('user_failed_login_ip_limit', 4000);
+    $flood_config->set('ip_limit', 4000);
     // Set the per-user login limit.
-    variable_set('user_failed_login_user_limit', 3);
+    $flood_config->set('user_limit', 3);
 
     $user1 = $this->drupalCreateUser(array());
     $incorrect_user1 = clone $user1;
@@ -139,7 +141,7 @@ class UserLoginTest extends WebTestBase {
     $this->assertNoFieldByXPath("//input[@name='pass' and @value!='']", NULL, t('Password value attribute is blank.'));
     if (isset($flood_trigger)) {
       if ($flood_trigger == 'user') {
-        $this->assertRaw(format_plural(variable_get('user_failed_login_user_limit', 5), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
+        $this->assertRaw(format_plural(config('user.flood')->get('user_limit'), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
       }
       else {
         // No uid, so the limit is IP-based.
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 9dd47da..d256ec9 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1638,19 +1638,20 @@ function user_login_name_validate($form, &$form_state) {
  */
 function user_login_authenticate_validate($form, &$form_state) {
   $password = trim($form_state['values']['pass']);
+  $flood_config = config('user.flood');
   if (!empty($form_state['values']['name']) && !empty($password)) {
     // 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 (!flood_is_allowed('failed_login_attempt_ip', variable_get('user_failed_login_ip_limit', 50), variable_get('user_failed_login_ip_window', 3600))) {
+    if (!flood_is_allowed('failed_login_attempt_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
       $form_state['flood_control_triggered'] = 'ip';
       return;
     }
     $account = db_query("SELECT * FROM {users} WHERE name = :name AND status = 1", array(':name' => $form_state['values']['name']))->fetchObject();
     if ($account) {
-      if (variable_get('user_failed_login_identifier_uid_only', FALSE)) {
+      if ($flood_config->get('identifier_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->uid;
@@ -1665,7 +1666,7 @@ function user_login_authenticate_validate($form, &$form_state) {
 
       // Don't allow login if the limit for this user has been reached.
       // Default is to allow 5 failed attempts every 6 hours.
-      if (!flood_is_allowed('failed_login_attempt_user', variable_get('user_failed_login_user_limit', 5), variable_get('user_failed_login_user_window', 21600), $identifier)) {
+      if (!flood_is_allowed('failed_login_attempt_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
         $form_state['flood_control_triggered'] = 'user';
         return;
       }
@@ -1684,17 +1685,18 @@ function user_login_authenticate_validate($form, &$form_state) {
  * be the last one.
  */
 function user_login_final_validate($form, &$form_state) {
+  $flood_config = config('user.flood');
   if (empty($form_state['uid'])) {
     // Always register an IP-based failed login event.
-    flood_register_event('failed_login_attempt_ip', variable_get('user_failed_login_ip_window', 3600));
+    flood_register_event('failed_login_attempt_ip', $flood_config->get('ip_window'));
     // Register a per-user failed login event.
     if (isset($form_state['flood_control_user_identifier'])) {
-      flood_register_event('failed_login_attempt_user', variable_get('user_failed_login_user_window', 21600), $form_state['flood_control_user_identifier']);
+      flood_register_event('failed_login_attempt_user', $flood_config->get('user_window'), $form_state['flood_control_user_identifier']);
     }
 
     if (isset($form_state['flood_control_triggered'])) {
       if ($form_state['flood_control_triggered'] == 'user') {
-        form_set_error('name', format_plural(variable_get('user_failed_login_user_limit', 5), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
+        form_set_error('name', format_plural($flood_config->get('user_limit'), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
       }
       else {
         // We did not find a uid, so the limit is IP-based.
