2fa UI improvements
This commit is contained in:
parent
5f838208e8
commit
ae127558b5
|
|
@ -5,6 +5,7 @@
|
||||||
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
||||||
<h2>@ViewData["Title"]</h2>
|
<h2>@ViewData["Title"]</h2>
|
||||||
|
|
||||||
<div class="alert alert-warning" role="alert">
|
<div class="alert alert-warning" role="alert">
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,9 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
public async Task<IActionResult> OnGet()
|
public async Task<IActionResult> OnGet()
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
@ -53,7 +56,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation("User with ID '{UserId}' has disabled 2fa.", _userManager.GetUserId(User));
|
_logger.LogInformation("User with ID '{UserId}' has disabled 2fa.", _userManager.GetUserId(User));
|
||||||
|
StatusMessage = "2fa has been disabled. You can reenable 2fa when you setup an authenticator app";
|
||||||
return RedirectToPage("./TwoFactorAuthentication");
|
return RedirectToPage("./TwoFactorAuthentication");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
<div>
|
<div>
|
||||||
<p>To use an authenticator app go through the following steps:</p>
|
<p>To use an authenticator app go through the following steps:</p>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -38,6 +37,9 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
[TempData]
|
[TempData]
|
||||||
public string[] RecoveryCodes { get; set; }
|
public string[] RecoveryCodes { get; set; }
|
||||||
|
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
[BindProperty]
|
[BindProperty]
|
||||||
public InputModel Input { get; set; }
|
public InputModel Input { get; set; }
|
||||||
|
|
||||||
|
|
@ -93,9 +95,18 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
await _userManager.SetTwoFactorEnabledAsync(user, true);
|
await _userManager.SetTwoFactorEnabledAsync(user, true);
|
||||||
_logger.LogInformation("User with ID '{UserId}' has enabled 2FA with an authenticator app.", user.Id);
|
_logger.LogInformation("User with ID '{UserId}' has enabled 2FA with an authenticator app.", user.Id);
|
||||||
|
|
||||||
var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
|
StatusMessage = "Your authenticator app has been verified.";
|
||||||
RecoveryCodes = recoveryCodes.ToArray();
|
|
||||||
return RedirectToPage("./ShowRecoveryCodes");
|
if (await _userManager.CountRecoveryCodesAsync(user) == 0)
|
||||||
|
{
|
||||||
|
var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
|
||||||
|
RecoveryCodes = recoveryCodes.ToArray();
|
||||||
|
return RedirectToPage("./ShowRecoveryCodes");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return RedirectToPage("./TwoFactorAuthentication");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadSharedKeyAndQrCodeUriAsync(IdentityUser user)
|
private async Task LoadSharedKeyAndQrCodeUriAsync(IdentityUser user)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
<div class="alert alert-warning" role="alert">
|
<div class="alert alert-warning" role="alert">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
[TempData]
|
[TempData]
|
||||||
public string[] RecoveryCodes { get; set; }
|
public string[] RecoveryCodes { get; set; }
|
||||||
|
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
public async Task<IActionResult> OnGetAsync()
|
public async Task<IActionResult> OnGetAsync()
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
@ -59,7 +62,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
RecoveryCodes = recoveryCodes.ToArray();
|
RecoveryCodes = recoveryCodes.ToArray();
|
||||||
|
|
||||||
_logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", user.Id);
|
_logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", user.Id);
|
||||||
|
StatusMessage = "You have generated new recovery codes.";
|
||||||
return RedirectToPage("./ShowRecoveryCodes");
|
return RedirectToPage("./ShowRecoveryCodes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
<div class="alert alert-warning" role="alert">
|
<div class="alert alert-warning" role="alert">
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -12,7 +13,7 @@
|
||||||
<strong>If you reset your authenticator key your authenticator app will not work until you reconfigure it.</strong>
|
<strong>If you reset your authenticator key your authenticator app will not work until you reconfigure it.</strong>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
This process disables 2FA until you verify your authenticator app and will also reset your 2FA recovery codes.
|
This process disables 2FA until you verify your authenticator app.
|
||||||
If you do not complete your authenticator app configuration you may lose access to your account.
|
If you do not complete your authenticator app configuration you may lose access to your account.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
@ -21,6 +20,10 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
public async Task<IActionResult> OnGet()
|
public async Task<IActionResult> OnGet()
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
@ -44,6 +47,8 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
await _userManager.ResetAuthenticatorKeyAsync(user);
|
await _userManager.ResetAuthenticatorKeyAsync(user);
|
||||||
_logger.LogInformation("User with ID '{UserId}' has reset their authentication app key.", user.Id);
|
_logger.LogInformation("User with ID '{UserId}' has reset their authentication app key.", user.Id);
|
||||||
|
|
||||||
|
StatusMessage = "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.";
|
||||||
|
|
||||||
return RedirectToPage("./EnableAuthenticator");
|
return RedirectToPage("./EnableAuthenticator");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
ViewData["ActivePage"] = "TwoFactorAuthentication";
|
ViewData["ActivePage"] = "TwoFactorAuthentication";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
<div class="alert alert-warning" role="alert">
|
<div class="alert alert-warning" role="alert">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
{
|
{
|
||||||
|
|
@ -15,6 +11,9 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
[TempData]
|
[TempData]
|
||||||
public string[] RecoveryCodes { get; set; }
|
public string[] RecoveryCodes { get; set; }
|
||||||
|
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
public IActionResult OnGet()
|
public IActionResult OnGet()
|
||||||
{
|
{
|
||||||
if (RecoveryCodes == null || RecoveryCodes.Length == 0)
|
if (RecoveryCodes == null || RecoveryCodes.Length == 0)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
ViewData["Title"] = "Two-factor authentication (2FA)";
|
ViewData["Title"] = "Two-factor authentication (2FA)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Html.Partial("_StatusMessage", Model.StatusMessage)
|
||||||
<h4>@ViewData["Title"]</h4>
|
<h4>@ViewData["Title"]</h4>
|
||||||
@if (Model.Is2faEnabled)
|
@if (Model.Is2faEnabled)
|
||||||
{
|
{
|
||||||
|
|
@ -29,6 +30,12 @@
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Model.IsMachineRemembered)
|
||||||
|
{
|
||||||
|
<form method="post" style="display: inline-block">
|
||||||
|
<button type="submit" class="btn btn-default">Forget this browser</button>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
<a asp-page="./Disable2fa" class="btn btn-default">Disable 2FA</a>
|
<a asp-page="./Disable2fa" class="btn btn-default">Disable 2FA</a>
|
||||||
<a asp-page="./GenerateRecoveryCodes" class="btn btn-default">Reset recovery codes</a>
|
<a asp-page="./GenerateRecoveryCodes" class="btn btn-default">Reset recovery codes</a>
|
||||||
}
|
}
|
||||||
|
|
@ -40,10 +47,10 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a asp-page="./EnableAuthenticator" class="btn btn-default">Configure authenticator app</a>
|
<a asp-page="./EnableAuthenticator" class="btn btn-default">Setup authenticator app</a>
|
||||||
<a asp-page="./ResetAuthenticator" class="btn btn-default">Reset authenticator app</a>
|
<a asp-page="./ResetAuthenticator" class="btn btn-default">Reset authenticator app</a>
|
||||||
}
|
}
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
<partial name="_ValidationScriptsPartial" />
|
<partial name="_ValidationScriptsPartial" />
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
|
|
@ -29,9 +28,13 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
|
|
||||||
public int RecoveryCodesLeft { get; set; }
|
public int RecoveryCodesLeft { get; set; }
|
||||||
|
|
||||||
[BindProperty]
|
|
||||||
public bool Is2faEnabled { get; set; }
|
public bool Is2faEnabled { get; set; }
|
||||||
|
|
||||||
|
public bool IsMachineRemembered { get; set; }
|
||||||
|
|
||||||
|
[TempData]
|
||||||
|
public string StatusMessage { get; set; }
|
||||||
|
|
||||||
public async Task<IActionResult> OnGet()
|
public async Task<IActionResult> OnGet()
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
@ -42,9 +45,23 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
|
||||||
|
|
||||||
HasAuthenticator = await _userManager.GetAuthenticatorKeyAsync(user) != null;
|
HasAuthenticator = await _userManager.GetAuthenticatorKeyAsync(user) != null;
|
||||||
Is2faEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
|
Is2faEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
|
||||||
|
IsMachineRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user);
|
||||||
RecoveryCodesLeft = await _userManager.CountRecoveryCodesAsync(user);
|
RecoveryCodesLeft = await _userManager.CountRecoveryCodesAsync(user);
|
||||||
|
|
||||||
return Page();
|
return Page();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> OnPost()
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await _signInManager.ForgetTwoFactorClientAsync();
|
||||||
|
StatusMessage = "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.";
|
||||||
|
return RedirectToPage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue