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..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; @@ -15,7 +17,6 @@ internal sealed class IdentityRedirectManager(NavigationManager navigationManage MaxAge = TimeSpan.FromSeconds(5), }; - [DoesNotReturn] public void RedirectTo(string? uri) { uri ??= ""; @@ -26,13 +27,9 @@ 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."); } - [DoesNotReturn] public void RedirectTo(string uri, Dictionary queryParameters) { var uriWithoutQuery = navigationManager.ToAbsoluteUri(uri).GetLeftPart(UriPartial.Path); @@ -40,7 +37,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 +45,11 @@ 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); + + 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 86e027c0b6ee..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/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..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 @@ -41,7 +41,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private bool hasPassword; [CascadingParameter] @@ -52,7 +52,13 @@ 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; + } + hasPassword = await UserManager.HasPasswordAsync(user); if (!hasPassword) { @@ -62,6 +68,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..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 @@ -40,7 +39,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private bool requirePassword; [CascadingParameter] @@ -52,12 +51,23 @@ protected override async Task OnInitializedAsync() { Input ??= new(); - user = await UserAccessor.GetRequiredUserAsync(HttpContext); + user = await UserManager.GetUserAsync(HttpContext.User); + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } requirePassword = await UserManager.HasPasswordAsync(user); } private async Task OnValidSubmitAsync() { + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + 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..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 @@ -31,14 +30,19 @@ @code { - private ApplicationUser user = default!; + private ApplicationUser? user; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; 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 (HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) { @@ -48,6 +52,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..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 @@ -55,7 +55,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private string? email; private bool isEmailConfirmed; @@ -67,7 +67,13 @@ 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; + } + email = await UserManager.GetEmailAsync(user); isEmailConfirmed = await UserManager.IsEmailConfirmedAsync(user); @@ -82,6 +88,12 @@ return; } + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + var userId = await UserManager.GetUserIdAsync(user); var code = await UserManager.GenerateChangeEmailTokenAsync(user, Input.NewEmail); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); @@ -101,6 +113,12 @@ return; } + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + 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..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 @@ -70,7 +69,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; @@ -83,13 +82,22 @@ else protected override async Task OnInitializedAsync() { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - - await LoadSharedKeyAndQrCodeUriAsync(user); + user = await UserManager.GetUserAsync(HttpContext.User); + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } } private async Task OnValidSubmitAsync() { + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + // 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..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 @@ -66,7 +65,7 @@ @code { public const string LinkLoginCallbackAction = "LinkLoginCallback"; - private ApplicationUser user = default!; + private ApplicationUser? user; private IList? currentLogins; private IList? otherLogins; private bool showRemoveButton; @@ -85,7 +84,13 @@ 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; + } + currentLogins = await UserManager.GetLoginsAsync(user); otherLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()) .Where(auth => currentLogins.All(ul => auth.Name != ul.LoginProvider)) @@ -107,6 +112,12 @@ private async Task OnSubmitAsync() { + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!); if (!result.Succeeded) { @@ -119,11 +130,18 @@ private async Task OnGetLinkLoginCallbackAsync() { + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + 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..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 @@ -40,7 +39,7 @@ else @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; private IEnumerable? recoveryCodes; [CascadingParameter] @@ -48,7 +47,12 @@ 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; + } var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user); if (!isTwoFactorEnabled) @@ -59,6 +63,12 @@ else private async Task OnSubmitAsync() { + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + 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..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 @@ -34,7 +33,7 @@ @code { - private ApplicationUser user = default!; + private ApplicationUser? user; private string? username; private string? phoneNumber; @@ -46,7 +45,13 @@ 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; + } + username = await UserManager.GetUserNameAsync(user); phoneNumber = await UserManager.GetPhoneNumberAsync(user); @@ -55,6 +60,12 @@ private async Task OnValidSubmitAsync() { + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + 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/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 c12e38094f76..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,7 +35,13 @@ 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; + } + 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..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 @@ -39,7 +38,7 @@ @code { private string? message; - private ApplicationUser user = default!; + private ApplicationUser? user; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; @@ -49,7 +48,12 @@ 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; + } var hasPassword = await UserManager.HasPasswordAsync(user); if (hasPassword) @@ -60,6 +64,12 @@ private async Task OnValidSubmitAsync() { + if (user is null) + { + RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + return; + } + 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..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,7 +81,13 @@ 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; + } + 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); 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",