diff --git a/core/modules/user/lib/Drupal/user/Form/UserLoginForm.php b/core/modules/user/lib/Drupal/user/Form/UserLoginForm.php
index 46744a4..a0dee53 100644
--- a/core/modules/user/lib/Drupal/user/Form/UserLoginForm.php
+++ b/core/modules/user/lib/Drupal/user/Form/UserLoginForm.php
@@ -165,7 +165,7 @@ public function validateAuthentication(array &$form, array &$form_state) {
       }
       // We are not limited by flood control, so try to authenticate.
       // Set $form_state['uid'] as a flag for self::validateFinal().
-      $form_state['uid'] = user_authenticate($form_state['values']['name'], $password);
+      $form_state['uid'] = \Drupal::service('user.auth')->authenticate($form_state['values']['name'], $password);
     }
   }
 
diff --git a/core/modules/user/lib/Drupal/user/UserAuth.php b/core/modules/user/lib/Drupal/user/UserAuth.php
new file mode 100644
index 0000000..aa8f25b
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/UserAuth.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\user\UserAuth.
+ */
+
+namespace Drupal\user;
+
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityStorageControllerInterface;
+use Drupal\Core\Password\PasswordInterface;
+
+/**
+ * Class UserAuth.
+ */
+class UserAuth {
+
+  /**
+   * The user storage.
+   *
+   * @var \Drupal\Core\Entity\EntityStorageControllerInterface
+   */
+  protected $storage;
+
+  /**
+   * The password service.
+   *
+   * @var \Drupal\Core\Password\PasswordInterface
+   */
+  protected $password;
+
+  /**
+   * Constructs a UserAuth object.
+   *
+   * @param EntityStorageControllerInterface $storage
+   * @param PasswordInterface $password
+   */
+  public function __construct(EntityManagerInterface $entity_manager, PasswordInterface $password) {
+    $this->storage = $entity_manager->getStorageController('user');
+    $this->password = $password;
+  }
+
+  /**
+   * Validates a user's login credentials locally.
+   *
+   * @param $name
+   *   User name to authenticate.
+   * @param $password
+   *   A plain-text password, such as trimmed text from form values.
+   * @return int|bool
+   *   The user's uid on success, or FALSE on failure to authenticate.
+   */
+  public function authenticate($name, $password) {
+    $uid = FALSE;
+
+    if (!empty($name) && !empty($password)) {
+      if ($account = $this->storage->loadByProperties(array('name' => $name))) {
+        if ($this->password->check($password, $account)) {
+          // Successful authentication.
+          $uid = $account->id();
+
+          // Update user to new password scheme if needed.
+          if ($this->password->userNeedsNewHash($account)) {
+            $account->setPassword($password);
+            $account->save();
+          }
+        }
+      }
+    }
+
+    return $uid;
+  }
+
+}
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 23d8706..efebc9c 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -33,3 +33,6 @@ services:
   user.permissions_hash:
     class: Drupal\user\PermissionsHash
     arguments: ['@private_key', '@cache.cache']
+  user.auth:
+    class: Drupal\user\UserAuth
+    arguements: ['@entity.manager', '@password']
