Split showing and generating recovery codes

This commit is contained in:
Pranav K 2018-01-11 17:23:17 -08:00
parent ce88212f49
commit e44cba9b75
6 changed files with 138 additions and 60 deletions

View File

@ -4,62 +4,62 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="Package Versions"> <PropertyGroup Label="Package Versions">
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview1-15651</InternalAspNetCoreSdkPackageVersion> <InternalAspNetCoreSdkPackageVersion>2.1.0-preview1-15651</InternalAspNetCoreSdkPackageVersion>
<MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion> <MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreAuthenticationCookiesPackageVersion>
<MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion> <MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreAuthenticationFacebookPackageVersion>
<MicrosoftAspNetCoreAuthenticationGooglePackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreAuthenticationGooglePackageVersion> <MicrosoftAspNetCoreAuthenticationGooglePackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreAuthenticationGooglePackageVersion>
<MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion> <MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreAuthenticationOpenIdConnectPackageVersion>
<MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreAuthenticationTwitterPackageVersion> <MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreAuthenticationTwitterPackageVersion>
<MicrosoftAspNetCoreAuthorizationPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreAuthorizationPackageVersion> <MicrosoftAspNetCoreAuthorizationPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreAuthorizationPackageVersion>
<MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion> <MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreCryptographyKeyDerivationPackageVersion>
<MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion> <MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreDataProtectionExtensionsPackageVersion>
<MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion> <MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion>
<MicrosoftAspNetCoreDiagnosticsPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreDiagnosticsPackageVersion> <MicrosoftAspNetCoreDiagnosticsPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreDiagnosticsPackageVersion>
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreHostingAbstractionsPackageVersion> <MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
<MicrosoftAspNetCoreHostingPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreHostingPackageVersion> <MicrosoftAspNetCoreHostingPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreHostingPackageVersion>
<MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreHttpAbstractionsPackageVersion> <MicrosoftAspNetCoreHttpAbstractionsPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreHttpAbstractionsPackageVersion>
<MicrosoftAspNetCoreHttpPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreHttpPackageVersion> <MicrosoftAspNetCoreHttpPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreHttpPackageVersion>
<MicrosoftAspNetCoreMvcPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreMvcPackageVersion> <MicrosoftAspNetCoreMvcPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreMvcPackageVersion>
<MicrosoftAspNetCoreMvcRazorViewCompilationPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreMvcRazorViewCompilationPackageVersion> <MicrosoftAspNetCoreMvcRazorViewCompilationPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreMvcRazorViewCompilationPackageVersion>
<MicrosoftAspNetCoreMvcTestingPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreMvcTestingPackageVersion> <MicrosoftAspNetCoreMvcTestingPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreMvcTestingPackageVersion>
<MicrosoftAspNetCoreRewritePackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreRewritePackageVersion> <MicrosoftAspNetCoreRewritePackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreRewritePackageVersion>
<MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreServerIISIntegrationPackageVersion> <MicrosoftAspNetCoreServerIISIntegrationPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreServerIISIntegrationPackageVersion>
<MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion> <MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreServerKestrelHttpsPackageVersion>
<MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreServerKestrelPackageVersion> <MicrosoftAspNetCoreServerKestrelPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreServerKestrelPackageVersion>
<MicrosoftAspNetCoreStaticFilesPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreStaticFilesPackageVersion> <MicrosoftAspNetCoreStaticFilesPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreStaticFilesPackageVersion>
<MicrosoftAspNetCoreTestHostPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreTestHostPackageVersion> <MicrosoftAspNetCoreTestHostPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreTestHostPackageVersion>
<MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview1-27965</MicrosoftAspNetCoreTestingPackageVersion> <MicrosoftAspNetCoreTestingPackageVersion>2.1.0-preview1-28061</MicrosoftAspNetCoreTestingPackageVersion>
<MicrosoftAspNetIdentityEntityFrameworkPackageVersion>2.2.1</MicrosoftAspNetIdentityEntityFrameworkPackageVersion> <MicrosoftAspNetIdentityEntityFrameworkPackageVersion>2.2.1</MicrosoftAspNetIdentityEntityFrameworkPackageVersion>
<MicrosoftAzureKeyVaultPackageVersion>2.3.2</MicrosoftAzureKeyVaultPackageVersion> <MicrosoftAzureKeyVaultPackageVersion>2.3.2</MicrosoftAzureKeyVaultPackageVersion>
<MicrosoftEntityFrameworkCoreInMemoryPackageVersion>2.1.0-preview1-27965</MicrosoftEntityFrameworkCoreInMemoryPackageVersion> <MicrosoftEntityFrameworkCoreInMemoryPackageVersion>2.1.0-preview1-28061</MicrosoftEntityFrameworkCoreInMemoryPackageVersion>
<MicrosoftEntityFrameworkCoreRelationalPackageVersion>2.1.0-preview1-27965</MicrosoftEntityFrameworkCoreRelationalPackageVersion> <MicrosoftEntityFrameworkCoreRelationalPackageVersion>2.1.0-preview1-28061</MicrosoftEntityFrameworkCoreRelationalPackageVersion>
<MicrosoftEntityFrameworkCoreSqlServerPackageVersion>2.1.0-preview1-27965</MicrosoftEntityFrameworkCoreSqlServerPackageVersion> <MicrosoftEntityFrameworkCoreSqlServerPackageVersion>2.1.0-preview1-28061</MicrosoftEntityFrameworkCoreSqlServerPackageVersion>
<MicrosoftEntityFrameworkCoreToolsDotNetPackageVersion>2.1.0-preview1-27965</MicrosoftEntityFrameworkCoreToolsDotNetPackageVersion> <MicrosoftEntityFrameworkCoreToolsDotNetPackageVersion>2.1.0-preview1-28061</MicrosoftEntityFrameworkCoreToolsDotNetPackageVersion>
<MicrosoftEntityFrameworkCoreToolsPackageVersion>2.1.0-preview1-27965</MicrosoftEntityFrameworkCoreToolsPackageVersion> <MicrosoftEntityFrameworkCoreToolsPackageVersion>2.1.0-preview1-28061</MicrosoftEntityFrameworkCoreToolsPackageVersion>
<MicrosoftExtensionsConfigurationBinderPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsConfigurationBinderPackageVersion> <MicrosoftExtensionsConfigurationBinderPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsConfigurationBinderPackageVersion>
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsConfigurationCommandLinePackageVersion> <MicrosoftExtensionsConfigurationCommandLinePackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
<MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion> <MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsConfigurationEnvironmentVariablesPackageVersion>
<MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion> <MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsConfigurationFileExtensionsPackageVersion>
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsConfigurationJsonPackageVersion> <MicrosoftExtensionsConfigurationJsonPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsConfigurationJsonPackageVersion>
<MicrosoftExtensionsConfigurationPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsConfigurationPackageVersion> <MicrosoftExtensionsConfigurationPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsConfigurationPackageVersion>
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsConfigurationUserSecretsPackageVersion> <MicrosoftExtensionsConfigurationUserSecretsPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsDependencyInjectionPackageVersion> <MicrosoftExtensionsDependencyInjectionPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsDependencyInjectionPackageVersion>
<MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion> <MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsFileProvidersEmbeddedPackageVersion>
<MicrosoftExtensionsLoggingConfigurationPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsLoggingConfigurationPackageVersion> <MicrosoftExtensionsLoggingConfigurationPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsLoggingConfigurationPackageVersion>
<MicrosoftExtensionsLoggingConsolePackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsLoggingConsolePackageVersion> <MicrosoftExtensionsLoggingConsolePackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsLoggingConsolePackageVersion>
<MicrosoftExtensionsLoggingDebugPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsLoggingDebugPackageVersion> <MicrosoftExtensionsLoggingDebugPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsLoggingDebugPackageVersion>
<MicrosoftExtensionsLoggingPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsLoggingPackageVersion> <MicrosoftExtensionsLoggingPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsLoggingPackageVersion>
<MicrosoftExtensionsLoggingTestingPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsLoggingTestingPackageVersion> <MicrosoftExtensionsLoggingTestingPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsLoggingTestingPackageVersion>
<MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion> <MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsOptionsConfigurationExtensionsPackageVersion>
<MicrosoftExtensionsOptionsPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsOptionsPackageVersion> <MicrosoftExtensionsOptionsPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsOptionsPackageVersion>
<MicrosoftExtensionsRazorViewsSourcesPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsRazorViewsSourcesPackageVersion> <MicrosoftExtensionsRazorViewsSourcesPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsRazorViewsSourcesPackageVersion>
<MicrosoftExtensionsSecurityHelperSourcesPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsSecurityHelperSourcesPackageVersion> <MicrosoftExtensionsSecurityHelperSourcesPackageVersion>2.1.0-preview1-28061</MicrosoftExtensionsSecurityHelperSourcesPackageVersion>
<MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>3.14.2</MicrosoftIdentityModelClientsActiveDirectoryPackageVersion> <MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>3.14.2</MicrosoftIdentityModelClientsActiveDirectoryPackageVersion>
<MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>5.2.0-preview2-41113220915</MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion> <MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>5.2.0-preview2-41113220915</MicrosoftIdentityModelProtocolsOpenIdConnectPackageVersion>
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion> <MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview1-26016-05</MicrosoftNETCoreApp21PackageVersion> <MicrosoftNETCoreApp21PackageVersion>2.1.0-preview1-26016-05</MicrosoftNETCoreApp21PackageVersion>
<MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion> <MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion>
<MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion> <MicrosoftOwinSecurityCookiesPackageVersion>3.0.1</MicrosoftOwinSecurityCookiesPackageVersion>
<MicrosoftOwinSecurityInteropPackageVersion>2.1.0-preview1-27965</MicrosoftOwinSecurityInteropPackageVersion> <MicrosoftOwinSecurityInteropPackageVersion>2.1.0-preview1-28061</MicrosoftOwinSecurityInteropPackageVersion>
<MoqPackageVersion>4.7.49</MoqPackageVersion> <MoqPackageVersion>4.7.49</MoqPackageVersion>
<SystemComponentModelAnnotationsPackageVersion>4.5.0-preview1-26016-05</SystemComponentModelAnnotationsPackageVersion> <SystemComponentModelAnnotationsPackageVersion>4.5.0-preview1-26016-05</SystemComponentModelAnnotationsPackageVersion>
<XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion> <XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion>

View File

@ -3,6 +3,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text; using System.Text;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -34,6 +35,9 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
public string AuthenticatorUri { get; set; } public string AuthenticatorUri { get; set; }
[TempData]
public string[] RecoveryCodes { get; set; }
[BindProperty] [BindProperty]
public InputModel Input { get; set; } public InputModel Input { get; set; }
@ -88,7 +92,10 @@ 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);
return RedirectToPage("./GenerateRecoveryCodes");
var recoveryCodes = await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
RecoveryCodes = recoveryCodes.ToArray();
return RedirectToPage("./ShowRecoveryCodes");
} }
private async Task LoadSharedKeyAndQrCodeUriAsync(IdentityUser user) private async Task LoadSharedKeyAndQrCodeUriAsync(IdentityUser user)

View File

@ -1,7 +1,7 @@
@page @page
@model GenerateRecoveryCodesModel @model GenerateRecoveryCodesModel
@{ @{
ViewData["Title"] = "Recovery codes"; ViewData["Title"] = "Generate two-factor authentication (2FA) recovery codes";
ViewData["ActivePage"] = "TwoFactorAuthentication"; ViewData["ActivePage"] = "TwoFactorAuthentication";
} }
@ -14,12 +14,13 @@
<p> <p>
If you lose your device and don't have the recovery codes you will lose access to your account. If you lose your device and don't have the recovery codes you will lose access to your account.
</p> </p>
<p>
Generating new recovery codes does not change the keys used in authenticator apps. If you wish to change the key
used in an authenticator app you should <a asp-page="./ResetAuthenticator">reset your authenticator keys.</a>
</p>
</div>
<div>
<form method="post" class="form-group">
<button class="btn btn-danger" type="submit">Generate Recovery Codes</button>
</form>
</div> </div>
<div class="row">
<div class="col-md-12">
@for (var row = 0; row < Model.RecoveryCodes.Count(); row += 2)
{
<code>@Model.RecoveryCodes[row]</code><text>&nbsp;</text><code>@Model.RecoveryCodes[row + 1]</code><br />
}
</div>
</div>

View File

@ -23,6 +23,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
_logger = logger; _logger = logger;
} }
[TempData]
public string[] RecoveryCodes { get; set; } public string[] RecoveryCodes { get; set; }
public async Task<IActionResult> OnGetAsync() public async Task<IActionResult> OnGetAsync()
@ -33,6 +34,22 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
} }
if (!user.TwoFactorEnabled)
{
throw new InvalidOperationException($"Cannot generate recovery codes for user with ID '{user.Id}' because they do not have 2FA enabled.");
}
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
if (!user.TwoFactorEnabled) if (!user.TwoFactorEnabled)
{ {
throw new InvalidOperationException($"Cannot generate recovery codes for user with ID '{user.Id}' as they do not have 2FA enabled."); throw new InvalidOperationException($"Cannot generate recovery codes for user with ID '{user.Id}' as they do not have 2FA enabled.");
@ -43,7 +60,7 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
_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);
return Page(); return RedirectToPage("./ShowRecoveryCodes");
} }
} }
} }

View File

@ -0,0 +1,25 @@
@page
@model ShowRecoveryCodesModel
@{
ViewData["Title"] = "Recovery codes";
ViewData["ActivePage"] = "TwoFactorAuthentication";
}
<h4>@ViewData["Title"]</h4>
<div class="alert alert-warning" role="alert">
<p>
<span class="glyphicon glyphicon-warning-sign"></span>
<strong>Put these codes in a safe place.</strong>
</p>
<p>
If you lose your device and don't have the recovery codes you will lose access to your account.
</p>
</div>
<div class="row">
<div class="col-md-12">
@for (var row = 0; row < Model.RecoveryCodes.Length; row += 2)
{
<code>@Model.RecoveryCodes[row]</code><text>&nbsp;</text><code>@Model.RecoveryCodes[row + 1]</code><br />
}
</div>
</div>

View File

@ -0,0 +1,28 @@
// 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.
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
{
public class ShowRecoveryCodesModel : PageModel
{
[TempData]
public string[] RecoveryCodes { get; set; }
public IActionResult OnGet()
{
if (RecoveryCodes == null || RecoveryCodes.Length == 0)
{
return RedirectToPage("./TwoFactorAuthentication");
}
return Page();
}
}
}