I have a Blazor .Net 8 server application, with render mode per component. For authentication I use Microsoft Identity. When starting the application, I create an admin, if it does not already exist, in Program.cs. This works perfectly and I can also log in with it.
using (var scope = app.Services.CreateScope()){var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager>();var userManager = scope.ServiceProvider.GetRequiredService<UserManager>();
var roles = new[] { "Admin", "User" };foreach (var role in roles){ if (!await roleManager.RoleExistsAsync(role)) { await roleManager.CreateAsync(new IdentityRole(role)); }}var userEmail = "email";var userPassword = "pwd";var user = await userManager.FindByEmailAsync(userEmail);if (user == null){ var newUser = new SvptUser { UserName = userEmail, Email = userEmail, EmailConfirmed = true }; var result = await userManager.CreateAsync(newUser, userPassword); if (result.Succeeded) { await userManager.AddToRoleAsync(newUser, roles.First()); } else { foreach (var error in result.Errors) { Console.WriteLine($"Error creating specific admin: {error.Description}"); } }}}
In the later code I created a service for the admin dashboard. This makes it possible for the admin to create customers via the dashboard and they receive an email with their login details.
private async void SendInvitation(){ if (!string.IsNullOrWhiteSpace(NewCustomer.Name) && !string.IsNullOrWhiteSpace(NewCustomer.Email)) { var parts = NewCustomer.Name.Trim() .ToLower() .Split('', StringSplitOptions.RemoveEmptyEntries); var validUserName = string.Join(".", parts); var svptUser = new SvptUser { UserName = validUserName, Email = NewCustomer.Email, PhoneNumber = NewCustomer.Number, }; var success = await userService.CreateNewSvptUser(svptUser); if (!success) { ErrorMessage = "Kunde konnte nicht hinzugefügt werden!"; StateHasChanged(); } else { Customers.Add(new DashboardCustomerViewModel { Email = svptUser.Email, HasSubmittedFeedback = svptUser.HasSubmittedFeedback, Name = svptUser.UserName ?? string.Empty, Roles = new List<string>() }); ShowAddForm = false; StateHasChanged(); } } else { ErrorMessage = "Name und Emails sind pflicht!"; StateHasChanged(); }} public async Task<bool> CreateNewSvptUser(SvptUser user){ var alreadyExists = await _userManager.FindByEmailAsync(user.Email ?? string.Empty); if (alreadyExists != null) { return false; } try { var password = GenerateSecurePassword(); user.EmailConfirmed = true; var result = await _userManager.CreateAsync(user, password); var roleresult = await _userManager.AddToRoleAsync(user, userRole); if (!result.Succeeded && !roleresult.Succeeded) { foreach (var error in result.Errors) { Console.WriteLine($"{error.Code}, {error.Description}"); }; return result.Succeeded; } var successMail = await _emailService.SendEmailAsync( user.Email, "Einladung Svpt Nutrition", user.UserName, user.Email, password); if (!successMail) { await _userManager.DeleteAsync(user); return false; } return result.Succeeded; } catch (Exception ex) { Console.WriteLine(ex.Message); return false; }}private static string GenerateSecurePassword(int length = 12){ const string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const string lowercase = "abcdefghijklmnopqrstuvwxyz"; const string digits = "0123456789"; const string special = "!@#$%^&*()_-+=<>?"; var random = new Random(); var passwordChars = new List<char>{ uppercase[random.Next(uppercase.Length)], lowercase[random.Next(lowercase.Length)], digits[random.Next(digits.Length)], special[random.Next(special.Length)]}; string allChars = uppercase + lowercase + digits + special; for (int i = passwordChars.Count; i < length; i++) { passwordChars.Add(allChars[random.Next(allChars.Length)]); } return new string(passwordChars.OrderBy(_ => random.Next()).ToArray());}If I then try to log in with these new login details, it does not work. I do the whole thing in the browser's incognitor mode.
When I enter the email and password, I get the error message “Error: Invalid login attempt.”, although these are clearly correct. Does anyone know why this error occurs, or how I can find the error, as I cannot debug the SignInManager class from Microsoft identity?