diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
index ad45303fa7c3b2cc67a784254ef4b960cb3cbb0c..19aba58b0562ca5732acb1231a64c4fd2aaaf682 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -338,4 +338,14 @@ class DefaultTokenProvider implements IProvider {
 		}
 	}
 
+	public function markPasswordInvalid(IToken $token, string $tokenId) {
+		if (!($token instanceof DefaultToken)) {
+			throw new InvalidTokenException();
+		}
+
+		//No need to mark as invalid. We just invalide default tokens
+		$this->invalidateToken($tokenId);
+	}
+
+
 }
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
index ab46bd121262af3882dc066fd4116929e182a77a..d1b067868b4c0d0008aa60b3ec874eed25575d00 100644
--- a/lib/private/Authentication/Token/IProvider.php
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -156,4 +156,12 @@ interface IProvider {
 	 * @return IToken
 	 */
 	public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken;
+
+	/**
+	 * Marks a token as having an invalid password.
+	 *
+	 * @param IToken $token
+	 * @param string $tokenId
+	 */
+	public function markPasswordInvalid(IToken $token, string $tokenId);
 }
diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php
index 254a1598943d287e3bce9fcbb269969e55f8684c..711d211039396192e4a048778ef336600ea78f89 100644
--- a/lib/private/Authentication/Token/Manager.php
+++ b/lib/private/Authentication/Token/Manager.php
@@ -227,4 +227,9 @@ class Manager implements IProvider {
 		}
 		throw new InvalidTokenException();
 	}
+
+
+	public function markPasswordInvalid(IToken $token, string $tokenId) {
+		$this->getProvider($token)->markPasswordInvalid($token, $tokenId);
+	}
 }
diff --git a/lib/private/Authentication/Token/PublicKeyToken.php b/lib/private/Authentication/Token/PublicKeyToken.php
index 0e793ce8c7c5a79912bea250488b6a6c0dfd2f9f..9896915ca33ef961c032751aa1fb607ece518730 100644
--- a/lib/private/Authentication/Token/PublicKeyToken.php
+++ b/lib/private/Authentication/Token/PublicKeyToken.php
@@ -43,6 +43,8 @@ use OCP\AppFramework\Db\Entity;
  * @method string getPublicKey()
  * @method void setPublicKey(string $key)
  * @method void setVersion(int $version)
+ * @method bool getPasswordInvalid()
+ * @method void setPasswordInvalid(bool $invalid);
  */
 class PublicKeyToken extends Entity implements IToken {
 
@@ -90,6 +92,9 @@ class PublicKeyToken extends Entity implements IToken {
 	/** @var int */
 	protected $version;
 
+	/** @var bool */
+	protected $passwordInvalid;
+
 	public function __construct() {
 		$this->addType('uid', 'string');
 		$this->addType('loginName', 'string');
@@ -105,6 +110,7 @@ class PublicKeyToken extends Entity implements IToken {
 		$this->addType('publicKey', 'string');
 		$this->addType('privateKey', 'string');
 		$this->addType('version', 'int');
+		$this->addType('passwordInvalid', 'bool');
 	}
 
 	public function getId(): int {
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index 7e98ee939cec12600f2e340de5a5dbd347a56125..9afdb5a8ff52fd097072d42911f72bb62d49af85 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -317,4 +317,15 @@ class PublicKeyTokenProvider implements IProvider {
 
 		return $dbToken;
 	}
+
+	public function markPasswordInvalid(IToken $token, string $tokenId) {
+		if (!($token instanceof PublicKeyToken)) {
+			throw new InvalidTokenException();
+		}
+
+		$token->setPasswordInvalid(true);
+		$this->mapper->update($token);
+	}
+
+
 }
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index 5593e178ca3c0ea1c63fb419122329192f7441b3..8ac42eac4eb12222617afe6566ca6794b5786a90 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -694,12 +694,19 @@ class Session implements IUserSession, Emitter {
 			return true;
 		}
 
-		if ($this->manager->checkPassword($dbToken->getLoginName(), $pwd) === false
-			|| (!is_null($this->activeUser) && !$this->activeUser->isEnabled())) {
+		// Invalidate token if the user is no longer active
+		if (!is_null($this->activeUser) && !$this->activeUser->isEnabled()) {
 			$this->tokenProvider->invalidateToken($token);
-			// Password has changed or user was disabled -> log user out
 			return false;
 		}
+
+		// If the token password is no longer valid mark it as such
+		if ($this->manager->checkPassword($dbToken->getLoginName(), $pwd) === false) {
+			$this->tokenProvider->markPasswordInvalid($dbToken, $token);
+			// User is logged out
+			return false;
+		}
+
 		$dbToken->setLastCheck($now);
 		return true;
 	}
diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php
index 24677b57dd67d0ac4ae111c610525f02feb347ec..81ceade9e02c41da5ad4291aef7190eb104f89eb 100644
--- a/tests/lib/User/SessionTest.php
+++ b/tests/lib/User/SessionTest.php
@@ -1017,10 +1017,8 @@ class SessionTest extends \Test\TestCase {
 			->method('getPassword')
 			->with($token, 'APP-PASSWORD')
 			->will($this->returnValue('123456'));
-		$userManager->expects($this->once())
-			->method('checkPassword')
-			->with('susan', '123456')
-			->will($this->returnValue(true));
+		$userManager->expects($this->never())
+			->method('checkPassword');
 		$user->expects($this->once())
 			->method('isEnabled')
 			->will($this->returnValue(false));