diff --git a/core/Controller/TwoFactorChallengeController.php b/core/Controller/TwoFactorChallengeController.php
index 499898de3bc2f52d29f608c2ccc769b2e43131cc..edaf3378cd8da331c77822e9f123c92d1fb6868c 100644
--- a/core/Controller/TwoFactorChallengeController.php
+++ b/core/Controller/TwoFactorChallengeController.php
@@ -61,6 +61,13 @@ class TwoFactorChallengeController extends Controller {
 		$this->urlGenerator = $urlGenerator;
 	}
 
+	/**
+	 * @return string
+	 */
+	protected function getLogoutAttribute() {
+		return \OC_User::getLogoutAttribute();
+	}
+
 	/**
 	 * @NoAdminRequired
 	 * @NoCSRFRequired
@@ -75,6 +82,7 @@ class TwoFactorChallengeController extends Controller {
 		$data = [
 			'providers' => $providers,
 			'redirect_url' => $redirect_url,
+			'logout_attribute' => $this->getLogoutAttribute(),
 		];
 		return new TemplateResponse($this->appName, 'twofactorselectchallenge', $data, 'guest');
 	}
@@ -106,6 +114,7 @@ class TwoFactorChallengeController extends Controller {
 		$data = [
 			'error' => $error,
 			'provider' => $provider,
+			'logout_attribute' => $this->getLogoutAttribute(),
 			'template' => $tmpl->fetchPage(),
 		];
 		return new TemplateResponse($this->appName, 'twofactorshowchallenge', $data, 'guest');
diff --git a/core/Middleware/TwoFactorMiddleware.php b/core/Middleware/TwoFactorMiddleware.php
index aa82897ad46408a206a7ea9fbccdc53ad10a02a4..0bad8a2c40f76ee30c7e46cff26cb816af9e404e 100644
--- a/core/Middleware/TwoFactorMiddleware.php
+++ b/core/Middleware/TwoFactorMiddleware.php
@@ -82,6 +82,11 @@ class TwoFactorMiddleware extends Middleware {
 			return;
 		}
 
+		if ($controller instanceof \OC\Core\Controller\LoginController && $methodName === 'logout') {
+			// Don't block the logout page, to allow canceling the 2FA
+			return;
+		}
+
 		if ($this->userSession->isLoggedIn()) {
 			$user = $this->userSession->getUser();
 
diff --git a/core/css/styles.css b/core/css/styles.css
index 837b3259781382681187cf467591fecc0271234b..0d7a5576e0c58277ac8cb8550344b6acae287ec9 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -37,6 +37,10 @@ body {
 	display: inline-block;
 }
 
+a.two-factor-cancel {
+	color: #fff;
+}
+
 .float-spinner {
 	height: 32px;
 	display: none;
diff --git a/core/templates/twofactorselectchallenge.php b/core/templates/twofactorselectchallenge.php
index 14d599aab3e97acd52fe893224e2015a9081dddb..4209beac4e69e1bbe1f1f58d471aa6b4518e7598 100644
--- a/core/templates/twofactorselectchallenge.php
+++ b/core/templates/twofactorselectchallenge.php
@@ -18,4 +18,5 @@
 	</li>
 <?php endforeach; ?>
 </ul>
-</fieldset>
\ No newline at end of file
+</fieldset>
+<a class="two-factor-cancel" <?php print_unescaped($_['logout_attribute']); ?>><?php p($l->t('Cancel login')) ?></a>
diff --git a/core/templates/twofactorshowchallenge.php b/core/templates/twofactorshowchallenge.php
index 66f5ed312ec640d554ebdb79712be7779e56371a..c5ee9aca4b4282ee2a39a2477712ac0f3384fac3 100644
--- a/core/templates/twofactorshowchallenge.php
+++ b/core/templates/twofactorshowchallenge.php
@@ -17,3 +17,4 @@ $template = $_['template'];
 <span class="warning"><?php p($l->t('An error occured while verifying the token')); ?></span>
 <?php endif; ?>
 <?php print_unescaped($template); ?>
+<a class="two-factor-cancel" <?php print_unescaped($_['logout_attribute']); ?>><?php p($l->t('Cancel login')) ?></a>
diff --git a/tests/Core/Controller/TwoFactorChallengeControllerTest.php b/tests/Core/Controller/TwoFactorChallengeControllerTest.php
index 2da6dcd52ac977a9b1490dae1aa28b9393f5e9fa..08d8dd1452ca3d4735e0654d30790db787dd10da 100644
--- a/tests/Core/Controller/TwoFactorChallengeControllerTest.php
+++ b/tests/Core/Controller/TwoFactorChallengeControllerTest.php
@@ -33,7 +33,7 @@ class TwoFactorChallengeControllerTest extends TestCase {
 	private $session;
 	private $urlGenerator;
 
-	/** TwoFactorChallengeController */
+	/** @var TwoFactorChallengeController|\PHPUnit_Framework_MockObject_MockObject */
 	private $controller;
 
 	protected function setUp() {
@@ -47,9 +47,20 @@ class TwoFactorChallengeControllerTest extends TestCase {
 		$this->session = $this->getMock('\OCP\ISession');
 		$this->urlGenerator = $this->getMock('\OCP\IURLGenerator');
 
-		$this->controller = new TwoFactorChallengeController(
-			'core', $this->request, $this->twoFactorManager, $this->userSession, $this->session, $this->urlGenerator
-		);
+		$this->controller = $this->getMockBuilder('OC\Core\Controller\TwoFactorChallengeController')
+			->setConstructorArgs([
+				'core',
+				$this->request,
+				$this->twoFactorManager,
+				$this->userSession,
+				$this->session,
+				$this->urlGenerator,
+			])
+			->setMethods(['getLogoutAttribute'])
+			->getMock();
+		$this->controller->expects($this->any())
+			->method('getLogoutAttribute')
+			->willReturn('logoutAttribute');
 	}
 
 	public function testSelectChallenge() {
@@ -70,6 +81,7 @@ class TwoFactorChallengeControllerTest extends TestCase {
 		$expected = new \OCP\AppFramework\Http\TemplateResponse('core', 'twofactorselectchallenge', [
 			'providers' => $providers,
 			'redirect_url' => '/some/url',
+			'logout_attribute' => 'logoutAttribute',
 		], 'guest');
 
 		$this->assertEquals($expected, $this->controller->selectChallenge('/some/url'));
@@ -110,6 +122,7 @@ class TwoFactorChallengeControllerTest extends TestCase {
 		$expected = new \OCP\AppFramework\Http\TemplateResponse('core', 'twofactorshowchallenge', [
 			'error' => true,
 			'provider' => $provider,
+			'logout_attribute' => 'logoutAttribute',
 			'template' => '<html/>',
 			], 'guest');