From 4db3b736f29eca6d76c5d177eb98e1ce37772aee Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Mon, 5 May 2025 08:56:08 +0200 Subject: [PATCH 1/5] Backport changes connected with identity template fix. --- .../Account/Pages/ConfirmEmail.razor | 1 + .../Account/Pages/ConfirmEmailChange.razor | 1 + .../Account/Pages/ExternalLogin.razor | 3 +++ .../Account/Pages/ForgotPassword.razor | 1 + .../Account/Pages/Manage/ChangePassword.razor | 12 +++++++++++- .../Pages/Manage/DeletePersonalData.razor | 12 ++++++++++-- .../Account/Pages/Manage/Disable2fa.razor | 9 +++++++-- .../Account/Pages/Manage/Email.razor | 17 ++++++++++++++++- .../Pages/Manage/EnableAuthenticator.razor | 13 ++++++++++--- .../Account/Pages/Manage/ExternalLogins.razor | 18 +++++++++++++++++- .../Pages/Manage/GenerateRecoveryCodes.razor | 11 ++++++++++- .../Account/Pages/Manage/Index.razor | 12 +++++++++++- .../Pages/Manage/ResetAuthenticator.razor | 5 +++++ .../Account/Pages/Manage/SetPassword.razor | 11 ++++++++++- .../Pages/Manage/TwoFactorAuthentication.razor | 5 +++++ .../Account/Pages/RegisterConfirmation.razor | 1 + .../Account/Pages/ResetPassword.razor | 2 ++ 17 files changed, 121 insertions(+), 13 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmail.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmail.razor index 830ee204c824..4254c0e65bae 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmail.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmail.razor @@ -30,6 +30,7 @@ if (UserId is null || Code is null) { RedirectManager.RedirectTo(""); + return; } var user = await UserManager.FindByIdAsync(UserId); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmailChange.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmailChange.razor index 478a810defc9..a1547b6fa41c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmailChange.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ConfirmEmailChange.razor @@ -36,6 +36,7 @@ { RedirectManager.RedirectToWithStatus( "Account/Login", "Error: Invalid email change confirmation link.", HttpContext); + return; } var user = await UserManager.FindByIdAsync(UserId); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ExternalLogin.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ExternalLogin.razor index 0e5200ecb4e5..611b3448d7f6 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ExternalLogin.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ExternalLogin.razor @@ -101,6 +101,7 @@ if (externalLoginInfo is null) { RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", HttpContext); + return; } // Sign in the user with this external login provider if the user already has a login. @@ -121,6 +122,7 @@ else if (result.IsLockedOut) { RedirectManager.RedirectTo("Account/Lockout"); + return; } // If the user does not have an account, then ask the user to create an account. @@ -135,6 +137,7 @@ if (externalLoginInfo is null) { RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during confirmation.", HttpContext); + return; } var emailStore = GetEmailStore(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ForgotPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ForgotPassword.razor index efe20b0f5639..1ab1bfa5fcb0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ForgotPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ForgotPassword.razor @@ -44,6 +44,7 @@ { // Don't reveal that the user does not exist or is not confirmed RedirectManager.RedirectTo("Account/ForgotPasswordConfirmation"); + return; } // For more information on how to enable account confirmation and password reset please diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor index dc21755a47b0..6278bd9c5e31 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor @@ -41,7 +41,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private bool hasPassword; [CascadingParameter] @@ -53,6 +53,11 @@ protected override async Task OnInitializedAsync() { user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } + hasPassword = await UserManager.HasPasswordAsync(user); if (!hasPassword) { @@ -62,6 +67,11 @@ private async Task OnValidSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; cannot change password."); + } + var changePasswordResult = await UserManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword); if (!changePasswordResult.Succeeded) { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor index d7bfb84d491b..b766b66a5c0e 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor @@ -40,7 +40,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private bool requirePassword; [CascadingParameter] @@ -53,11 +53,19 @@ { Input ??= new(); user = await UserAccessor.GetRequiredUserAsync(HttpContext); - requirePassword = await UserManager.HasPasswordAsync(user); + if (user is not null) + { + requirePassword = await UserManager.HasPasswordAsync(user); + } } private async Task OnValidSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to delete personal data."); + } + if (requirePassword && !await UserManager.CheckPasswordAsync(user, Input.Password)) { message = "Error: Incorrect password."; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor index d3969f457c9c..c64ab96d629c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor @@ -31,7 +31,7 @@ @code { - private ApplicationUser user = default!; + private ApplicationUser? user; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; @@ -40,7 +40,7 @@ { user = await UserAccessor.GetRequiredUserAsync(HttpContext); - if (HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) + if (user is not null && HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) { throw new InvalidOperationException("Cannot disable 2FA for user as it's not currently enabled."); } @@ -48,6 +48,11 @@ private async Task OnSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to disable 2FA."); + } + var disable2faResult = await UserManager.SetTwoFactorEnabledAsync(user, false); if (!disable2faResult.Succeeded) { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor index c8b1518061ae..08eb4589b86a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor @@ -55,7 +55,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private string? email; private bool isEmailConfirmed; @@ -68,6 +68,11 @@ protected override async Task OnInitializedAsync() { user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } + email = await UserManager.GetEmailAsync(user); isEmailConfirmed = await UserManager.IsEmailConfirmedAsync(user); @@ -82,6 +87,11 @@ return; } + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to manage email."); + } + var userId = await UserManager.GetUserIdAsync(user); var code = await UserManager.GenerateChangeEmailTokenAsync(user, Input.NewEmail); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); @@ -101,6 +111,11 @@ return; } + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to send verification email."); + } + var userId = await UserManager.GetUserIdAsync(user); var code = await UserManager.GenerateEmailConfirmationTokenAsync(user); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor index 1872e9e6c83b..d2e7cdd24813 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor @@ -70,7 +70,7 @@ else private const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6"; private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private string? sharedKey; private string? authenticatorUri; private IEnumerable? recoveryCodes; @@ -84,12 +84,19 @@ else protected override async Task OnInitializedAsync() { user = await UserAccessor.GetRequiredUserAsync(HttpContext); - - await LoadSharedKeyAndQrCodeUriAsync(user); + if (user is not null) + { + await LoadSharedKeyAndQrCodeUriAsync(user); + } } private async Task OnValidSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to configure authenticator app."); + } + // Strip spaces and hyphens var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor index 25a6b27926a0..ca95de6402dc 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor @@ -66,7 +66,7 @@ @code { public const string LinkLoginCallbackAction = "LinkLoginCallback"; - private ApplicationUser user = default!; + private ApplicationUser? user; private IList? currentLogins; private IList? otherLogins; private bool showRemoveButton; @@ -86,6 +86,11 @@ protected override async Task OnInitializedAsync() { user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } + currentLogins = await UserManager.GetLoginsAsync(user); otherLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()) .Where(auth => currentLogins.All(ul => auth.Name != ul.LoginProvider)) @@ -107,6 +112,11 @@ private async Task OnSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to remove external login."); + } + var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!); if (!result.Succeeded) { @@ -119,11 +129,17 @@ private async Task OnGetLinkLoginCallbackAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to add external login."); + } + var userId = await UserManager.GetUserIdAsync(user); var info = await SignInManager.GetExternalLoginInfoAsync(userId); if (info is null) { RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", HttpContext); + return; } var result = await UserManager.AddLoginAsync(user, info); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor index c63c765ab887..b03a2905200b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor @@ -40,7 +40,7 @@ else @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private IEnumerable? recoveryCodes; [CascadingParameter] @@ -49,6 +49,10 @@ else protected override async Task OnInitializedAsync() { user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user); if (!isTwoFactorEnabled) @@ -59,6 +63,11 @@ else private async Task OnSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to generate recovery codes."); + } + var userId = await UserManager.GetUserIdAsync(user); recoveryCodes = await UserManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10); message = "You have generated new recovery codes."; diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor index bff831a1d852..a5c47d666791 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor @@ -34,7 +34,7 @@ @code { - private ApplicationUser user = default!; + private ApplicationUser? user; private string? username; private string? phoneNumber; @@ -47,6 +47,11 @@ protected override async Task OnInitializedAsync() { user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } + username = await UserManager.GetUserNameAsync(user); phoneNumber = await UserManager.GetPhoneNumberAsync(user); @@ -55,6 +60,11 @@ private async Task OnValidSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to set phone number."); + } + if (Input.PhoneNumber != phoneNumber) { var setPhoneResult = await UserManager.SetPhoneNumberAsync(user, Input.PhoneNumber); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor index c12e38094f76..1ae1e884a9a5 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor @@ -37,6 +37,11 @@ private async Task OnSubmitAsync() { var user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } + await UserManager.SetTwoFactorEnabledAsync(user, false); await UserManager.ResetAuthenticatorKeyAsync(user); var userId = await UserManager.GetUserIdAsync(user); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor index 79eabe780fff..e56f1980af56 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor @@ -39,7 +39,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; @@ -50,6 +50,10 @@ protected override async Task OnInitializedAsync() { user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } var hasPassword = await UserManager.HasPasswordAsync(user); if (hasPassword) @@ -60,6 +64,11 @@ private async Task OnValidSubmitAsync() { + if (user is null) + { + throw new InvalidOperationException("User is not loaded; failed to set password."); + } + var addPasswordResult = await UserManager.AddPasswordAsync(user, Input.NewPassword!); if (!addPasswordResult.Succeeded) { diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor index d15097a9ed16..dab6b95429ec 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor @@ -83,6 +83,11 @@ else protected override async Task OnInitializedAsync() { var user = await UserAccessor.GetRequiredUserAsync(HttpContext); + if (user is null) + { + return; + } + canTrack = HttpContext.Features.Get()?.CanTrack ?? true; hasAuthenticator = await UserManager.GetAuthenticatorKeyAsync(user) is not null; is2faEnabled = await UserManager.GetTwoFactorEnabledAsync(user); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/RegisterConfirmation.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/RegisterConfirmation.razor index ec74ea584ef8..52ee9594920b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/RegisterConfirmation.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/RegisterConfirmation.razor @@ -46,6 +46,7 @@ else if (Email is null) { RedirectManager.RedirectTo(""); + return; } var user = await UserManager.FindByEmailAsync(Email); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ResetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ResetPassword.razor index 61e07c0b8de0..4c88c56665ae 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ResetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/ResetPassword.razor @@ -58,6 +58,7 @@ if (Code is null) { RedirectManager.RedirectTo("Account/InvalidPasswordReset"); + return; } Input.Code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(Code)); @@ -70,6 +71,7 @@ { // Don't reveal that the user does not exist RedirectManager.RedirectTo("Account/ResetPasswordConfirmation"); + return; } var result = await UserManager.ResetPasswordAsync(user, Input.Code, Input.Password); From 63f0095027471465d599ff5ca9b907e2b16c2d66 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Mon, 5 May 2025 11:57:21 +0200 Subject: [PATCH 2/5] Missing commit. --- .../Account/IdentityRedirectManager.cs | 20 +++++++++++-------- .../Account/IdentityUserAccessor.cs | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs index da85e6efd46d..692f51a57386 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs @@ -7,6 +7,12 @@ internal sealed class IdentityRedirectManager(NavigationManager navigationManage { public const string StatusCookieName = "Identity.StatusMessage"; + private const string _enableThrowNavigationException = "Microsoft.AspNetCore.Components.Endpoints.NavigationManager.EnableThrowNavigationException"; + + [FeatureSwitchDefinition("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.EnableThrowNavigationException")] + private static bool _throwNavigationException => + AppContext.TryGetSwitch(_enableThrowNavigationException, out var switchValue) && switchValue; + private static readonly CookieBuilder StatusCookieBuilder = new() { SameSite = SameSiteMode.Strict, @@ -15,7 +21,6 @@ internal sealed class IdentityRedirectManager(NavigationManager navigationManage MaxAge = TimeSpan.FromSeconds(5), }; - [DoesNotReturn] public void RedirectTo(string? uri) { uri ??= ""; @@ -26,13 +31,15 @@ public void RedirectTo(string? uri) uri = navigationManager.ToBaseRelativePath(uri); } - // During static rendering, NavigateTo throws a NavigationException which is handled by the framework as a redirect. - // So as long as this is called from a statically rendered Identity component, the InvalidOperationException is never thrown. navigationManager.NavigateTo(uri); - throw new InvalidOperationException($"{nameof(IdentityRedirectManager)} can only be used during static rendering."); + if (_throwNavigationException) + { + // During static rendering, NavigateTo throws a NavigationException which is handled by the framework as a redirect. + // So as long as this is called from a statically rendered Identity component, the InvalidOperationException is never thrown. + throw new InvalidOperationException($"{nameof(IdentityRedirectManager)} can only be used during static rendering."); + } } - [DoesNotReturn] public void RedirectTo(string uri, Dictionary queryParameters) { var uriWithoutQuery = navigationManager.ToAbsoluteUri(uri).GetLeftPart(UriPartial.Path); @@ -40,7 +47,6 @@ public void RedirectTo(string uri, Dictionary queryParameters) RedirectTo(newUri); } - [DoesNotReturn] public void RedirectToWithStatus(string uri, string message, HttpContext context) { context.Response.Cookies.Append(StatusCookieName, message, StatusCookieBuilder.Build(context)); @@ -49,10 +55,8 @@ public void RedirectToWithStatus(string uri, string message, HttpContext context private string CurrentPath => navigationManager.ToAbsoluteUri(navigationManager.Uri).GetLeftPart(UriPartial.Path); - [DoesNotReturn] public void RedirectToCurrentPage() => RedirectTo(CurrentPath); - [DoesNotReturn] public void RedirectToCurrentPageWithStatus(string message, HttpContext context) => RedirectToWithStatus(CurrentPath, message, context); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs index 86e027c0b6ee..077ef1a57fd0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs @@ -5,7 +5,7 @@ namespace BlazorWeb_CSharp.Components.Account; internal sealed class IdentityUserAccessor(UserManager userManager, IdentityRedirectManager redirectManager) { - public async Task GetRequiredUserAsync(HttpContext context) + public async Task GetRequiredUserAsync(HttpContext context) { var user = await userManager.GetUserAsync(context.User); From 6bb4132e4eb4def89a07222e304ae8e4369e798f Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Tue, 6 May 2025 13:58:18 +0200 Subject: [PATCH 3/5] Feedback: Remove the exception, even when the switch is set. --- .../Components/Account/IdentityRedirectManager.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs index 692f51a57386..a7de94ca41e2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs @@ -7,12 +7,6 @@ internal sealed class IdentityRedirectManager(NavigationManager navigationManage { public const string StatusCookieName = "Identity.StatusMessage"; - private const string _enableThrowNavigationException = "Microsoft.AspNetCore.Components.Endpoints.NavigationManager.EnableThrowNavigationException"; - - [FeatureSwitchDefinition("Microsoft.AspNetCore.Components.Endpoints.NavigationManager.EnableThrowNavigationException")] - private static bool _throwNavigationException => - AppContext.TryGetSwitch(_enableThrowNavigationException, out var switchValue) && switchValue; - private static readonly CookieBuilder StatusCookieBuilder = new() { SameSite = SameSiteMode.Strict, @@ -32,12 +26,6 @@ public void RedirectTo(string? uri) } navigationManager.NavigateTo(uri); - if (_throwNavigationException) - { - // During static rendering, NavigateTo throws a NavigationException which is handled by the framework as a redirect. - // So as long as this is called from a statically rendered Identity component, the InvalidOperationException is never thrown. - throw new InvalidOperationException($"{nameof(IdentityRedirectManager)} can only be used during static rendering."); - } } public void RedirectTo(string uri, Dictionary queryParameters) From eebe2c809c6084ae65b1c9c221a32b5cef5394a2 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Fri, 16 May 2025 08:47:56 +0200 Subject: [PATCH 4/5] Feedback. --- .../Account/IdentityRedirectManager.cs | 5 +++++ .../Account/IdentityUserAccessor.cs | 19 ------------------- .../Account/Pages/Manage/ChangePassword.razor | 5 +++-- .../Pages/Manage/DeletePersonalData.razor | 12 +++++++----- .../Account/Pages/Manage/Disable2fa.razor | 9 +++++++-- .../Account/Pages/Manage/Email.razor | 11 +++++++---- .../Pages/Manage/EnableAuthenticator.razor | 11 ++++++----- .../Account/Pages/Manage/ExternalLogins.razor | 10 ++++++---- .../Pages/Manage/GenerateRecoveryCodes.razor | 7 ++++--- .../Account/Pages/Manage/Index.razor | 7 ++++--- .../Account/Pages/Manage/PersonalData.razor | 13 +++++++++++-- .../Pages/Manage/ResetAuthenticator.razor | 4 ++-- .../Account/Pages/Manage/SetPassword.razor | 7 ++++--- .../Manage/TwoFactorAuthentication.razor | 4 ++-- .../BlazorWeb-CSharp/Program.Main.cs | 1 - .../BlazorWeb-CSharp/Program.cs | 1 - .../Templates.Tests/template-baselines.json | 9 --------- 17 files changed, 68 insertions(+), 67 deletions(-) delete mode 100644 src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs index a7de94ca41e2..dc31e3f44e74 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityRedirectManager.cs @@ -1,5 +1,7 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Identity; +using BlazorWeb_CSharp.Data; namespace BlazorWeb_CSharp.Components.Account; @@ -47,4 +49,7 @@ public void RedirectToWithStatus(string uri, string message, HttpContext context public void RedirectToCurrentPageWithStatus(string message, HttpContext context) => RedirectToWithStatus(CurrentPath, message, context); + + public void RedirectToInvalidUser(UserManager userManager, HttpContext context) + => RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs deleted file mode 100644 index 077ef1a57fd0..000000000000 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/IdentityUserAccessor.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.AspNetCore.Identity; -using BlazorWeb_CSharp.Data; - -namespace BlazorWeb_CSharp.Components.Account; - -internal sealed class IdentityUserAccessor(UserManager userManager, IdentityRedirectManager redirectManager) -{ - public async Task GetRequiredUserAsync(HttpContext context) - { - var user = await userManager.GetUserAsync(context.User); - - if (user is null) - { - redirectManager.RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context); - } - - return user; - } -} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor index 6278bd9c5e31..d4c6236a115a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ChangePassword.razor @@ -6,7 +6,7 @@ @inject UserManager UserManager @inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor +@inject RedirectManager RedirectManager @inject IdentityRedirectManager RedirectManager @inject ILogger Logger @@ -52,9 +52,10 @@ protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor index b766b66a5c0e..12dcd63bd78a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/DeletePersonalData.razor @@ -6,7 +6,6 @@ @inject UserManager UserManager @inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor @inject IdentityRedirectManager RedirectManager @inject ILogger Logger @@ -52,18 +51,21 @@ protected override async Task OnInitializedAsync() { Input ??= new(); - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - if (user is not null) + user = await UserManager.GetUserAsync(HttpContext.User); + if (user is null) { - requirePassword = await UserManager.HasPasswordAsync(user); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } + requirePassword = await UserManager.HasPasswordAsync(user); } private async Task OnValidSubmitAsync() { if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to delete personal data."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } if (requirePassword && !await UserManager.CheckPasswordAsync(user, Input.Password)) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor index c64ab96d629c..4e78d69b29f9 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor @@ -38,9 +38,14 @@ protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } - if (user is not null && HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) + if (HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) { throw new InvalidOperationException("Cannot disable 2FA for user as it's not currently enabled."); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor index 08eb4589b86a..5cbfdcb75024 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Email.razor @@ -9,8 +9,8 @@ @inject UserManager UserManager @inject IEmailSender EmailSender -@inject IdentityUserAccessor UserAccessor @inject NavigationManager NavigationManager +@inject IdentityRedirectManager RedirectManager Manage email @@ -67,9 +67,10 @@ protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } @@ -89,7 +90,8 @@ if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to manage email."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } var userId = await UserManager.GetUserIdAsync(user); @@ -113,7 +115,8 @@ if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to send verification email."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } var userId = await UserManager.GetUserIdAsync(user); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor index d2e7cdd24813..be8c1429e18b 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/EnableAuthenticator.razor @@ -8,7 +8,6 @@ @using BlazorWeb_CSharp.Data @inject UserManager UserManager -@inject IdentityUserAccessor UserAccessor @inject UrlEncoder UrlEncoder @inject IdentityRedirectManager RedirectManager @inject ILogger Logger @@ -83,10 +82,11 @@ else protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - if (user is not null) + user = await UserManager.GetUserAsync(HttpContext.User); + if (user is null) { - await LoadSharedKeyAndQrCodeUriAsync(user); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } } @@ -94,7 +94,8 @@ else { if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to configure authenticator app."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } // Strip spaces and hyphens diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor index ca95de6402dc..00794aa25f93 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ExternalLogins.razor @@ -6,7 +6,6 @@ @inject UserManager UserManager @inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor @inject IUserStore UserStore @inject IdentityRedirectManager RedirectManager @@ -85,9 +84,10 @@ protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } @@ -114,7 +114,8 @@ { if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to remove external login."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!); @@ -131,7 +132,8 @@ { if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to add external login."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } var userId = await UserManager.GetUserIdAsync(user); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor index b03a2905200b..3e62899c0a14 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor @@ -4,7 +4,6 @@ @using BlazorWeb_CSharp.Data @inject UserManager UserManager -@inject IdentityUserAccessor UserAccessor @inject IdentityRedirectManager RedirectManager @inject ILogger Logger @@ -48,9 +47,10 @@ else protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } @@ -65,7 +65,8 @@ else { if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to generate recovery codes."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } var userId = await UserManager.GetUserIdAsync(user); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor index a5c47d666791..b5ca1361af4e 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Index.razor @@ -6,7 +6,6 @@ @inject UserManager UserManager @inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor @inject IdentityRedirectManager RedirectManager Profile @@ -46,9 +45,10 @@ protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } @@ -62,7 +62,8 @@ { if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to set phone number."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } if (Input.PhoneNumber != phoneNumber) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor index 851eb54c8820..42dd6d52ada3 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/PersonalData.razor @@ -1,6 +1,10 @@ @page "/Account/Manage/PersonalData" -@inject IdentityUserAccessor UserAccessor +@using Microsoft.AspNetCore.Identity +@using BlazorWeb_CSharp.Data + +@inject UserManager UserManager +@inject IdentityRedirectManager RedirectManager Personal Data @@ -29,6 +33,11 @@ protected override async Task OnInitializedAsync() { - _ = await UserAccessor.GetRequiredUserAsync(HttpContext); + var user = await UserManager.GetUserAsync(HttpContext.User); + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor index 1ae1e884a9a5..c087a5eb6797 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/ResetAuthenticator.razor @@ -5,7 +5,6 @@ @inject UserManager UserManager @inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor @inject IdentityRedirectManager RedirectManager @inject ILogger Logger @@ -36,9 +35,10 @@ private async Task OnSubmitAsync() { - var user = await UserAccessor.GetRequiredUserAsync(HttpContext); + var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor index e56f1980af56..c9c7b26317cf 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/SetPassword.razor @@ -6,7 +6,6 @@ @inject UserManager UserManager @inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor @inject IdentityRedirectManager RedirectManager Set password @@ -49,9 +48,10 @@ protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } @@ -66,7 +66,8 @@ { if (user is null) { - throw new InvalidOperationException("User is not loaded; failed to set password."); + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; } var addPasswordResult = await UserManager.AddPasswordAsync(user, Input.NewPassword!); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor index dab6b95429ec..08fae2319374 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/TwoFactorAuthentication.razor @@ -6,7 +6,6 @@ @inject UserManager UserManager @inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor @inject IdentityRedirectManager RedirectManager Two-factor authentication (2FA) @@ -82,9 +81,10 @@ else protected override async Task OnInitializedAsync() { - var user = await UserAccessor.GetRequiredUserAsync(HttpContext); + var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.Main.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.Main.cs index 6a2069105227..d37d24553867 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.Main.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.Main.cs @@ -46,7 +46,6 @@ public static void Main(string[] args) #if (IndividualLocalAuth) builder.Services.AddCascadingAuthenticationState(); - builder.Services.AddScoped(); builder.Services.AddScoped(); #if (UseServer) builder.Services.AddScoped(); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.cs index b0186c948ca4..7ea8e5a50033 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Program.cs @@ -40,7 +40,6 @@ #if (IndividualLocalAuth) builder.Services.AddCascadingAuthenticationState(); -builder.Services.AddScoped(); builder.Services.AddScoped(); #if (UseServer) builder.Services.AddScoped(); diff --git a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json index dd5755ff3bbe..8922c10f4143 100644 --- a/src/ProjectTemplates/test/Templates.Tests/template-baselines.json +++ b/src/ProjectTemplates/test/Templates.Tests/template-baselines.json @@ -599,7 +599,6 @@ "Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs", "Components/Account/IdentityNoOpEmailSender.cs", "Components/Account/IdentityRedirectManager.cs", - "Components/Account/IdentityUserAccessor.cs", "Components/Account/Pages/AccessDenied.razor", "Components/Account/Pages/ConfirmEmail.razor", "Components/Account/Pages/ConfirmEmailChange.razor", @@ -788,7 +787,6 @@ "Components/Account/IdentityNoOpEmailSender.cs", "Components/Account/IdentityRedirectManager.cs", "Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs", - "Components/Account/IdentityUserAccessor.cs", "Components/Account/Pages/AccessDenied.razor", "Components/Account/Pages/ConfirmEmail.razor", "Components/Account/Pages/ConfirmEmailChange.razor", @@ -909,7 +907,6 @@ "Components/Account/IdentityNoOpEmailSender.cs", "Components/Account/IdentityRedirectManager.cs", "Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs", - "Components/Account/IdentityUserAccessor.cs", "Components/Account/Pages/AccessDenied.razor", "Components/Account/Pages/ConfirmEmail.razor", "Components/Account/Pages/ConfirmEmailChange.razor", @@ -1112,7 +1109,6 @@ "{ProjectName}/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs", "{ProjectName}/Components/Account/IdentityNoOpEmailSender.cs", "{ProjectName}/Components/Account/IdentityRedirectManager.cs", - "{ProjectName}/Components/Account/IdentityUserAccessor.cs", "{ProjectName}/Components/Account/Pages/AccessDenied.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmail.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmailChange.razor", @@ -1314,7 +1310,6 @@ "{ProjectName}/Components/Account/IdentityNoOpEmailSender.cs", "{ProjectName}/Components/Account/IdentityRedirectManager.cs", "{ProjectName}/Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs", - "{ProjectName}/Components/Account/IdentityUserAccessor.cs", "{ProjectName}/Components/Account/Pages/AccessDenied.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmail.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmailChange.razor", @@ -1756,7 +1751,6 @@ "{ProjectName}/Components/Account/IdentityNoOpEmailSender.cs", "{ProjectName}/Components/Account/IdentityRedirectManager.cs", "{ProjectName}/Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs", - "{ProjectName}/Components/Account/IdentityUserAccessor.cs", "{ProjectName}/Components/Account/Pages/AccessDenied.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmail.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmailChange.razor", @@ -1826,7 +1820,6 @@ "Components/Account/IdentityNoOpEmailSender.cs", "Components/Account/IdentityRedirectManager.cs", "Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs", - "Components/Account/IdentityUserAccessor.cs", "Components/Account/Pages/AccessDenied.razor", "Components/Account/Pages/ConfirmEmail.razor", "Components/Account/Pages/ConfirmEmailChange.razor", @@ -1962,7 +1955,6 @@ "{ProjectName}/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs", "{ProjectName}/Components/Account/IdentityNoOpEmailSender.cs", "{ProjectName}/Components/Account/IdentityRedirectManager.cs", - "{ProjectName}/Components/Account/IdentityUserAccessor.cs", "{ProjectName}/Components/Account/Pages/AccessDenied.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmail.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmailChange.razor", @@ -2090,7 +2082,6 @@ "{ProjectName}/Components/Account/IdentityNoOpEmailSender.cs", "{ProjectName}/Components/Account/IdentityRedirectManager.cs", "{ProjectName}/Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs", - "{ProjectName}/Components/Account/IdentityUserAccessor.cs", "{ProjectName}/Components/Account/Pages/AccessDenied.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmail.razor", "{ProjectName}/Components/Account/Pages/ConfirmEmailChange.razor", From 190eee31909367c73c6c57e47fc206b23adaf7c6 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Fri, 16 May 2025 12:29:13 +0200 Subject: [PATCH 5/5] Missing removal. --- .../Components/Account/Pages/Manage/Disable2fa.razor | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor index 4e78d69b29f9..edf406428ffd 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account/Pages/Manage/Disable2fa.razor @@ -4,7 +4,6 @@ @using BlazorWeb_CSharp.Data @inject UserManager UserManager -@inject IdentityUserAccessor UserAccessor @inject IdentityRedirectManager RedirectManager @inject ILogger Logger