Program.cs: public static async Task Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddDbContext(options => options.UseSqlServer( "Server=(localdb)\\MSSQLLocalDB;Database=CommunityWebsite_Database;Trusted_Connection=True;MultipleActiveResultSets=true" )); builder.Services.AddScoped(); builder.Services.AddControllersWithViews(); builder.Services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); builder.Services.Configure(options => { options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 10; options.Password.RequiredUniqueChars = 1; options.User.RequireUniqueEmail = true; }); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapRazorPages(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; UserManager userManager = services.GetService>(); var context = services.GetRequiredService(); await DbInitializer.Initialize(context, userManager); } await app.RunAsync(); } _Layout.cshtml: ... @if (User.Identity.IsAuthenticated){ } else { } ... Pages/Account/Register.cshtml: @model CommunityWebsite_Lexicon_Project.Models.LoginModel @{

Register

Email

Username

Password

Confirm Password

} @{ if (ViewBag.Message != null) {
@ViewBag.Message
} } } Pages/Account/Login.cshtml: @model LoginModel @{

Login

Username

Password

Confirm Password

Email

} @{ if (ViewBag.Message != null) {
@ViewBag.Message
} } Models/LoginModel.cs: using System.ComponentModel.DataAnnotations; using System.Xml.Linq; namespace CommunityWebsite_Lexicon_Project.Models { public class LoginModel { public string Username { get; set; } public string Email { get; set; } public string Password { get; set; } public string PasswordConfirm { get; set; } } } Controllers/AccountController.cs: using CommunityWebsite_Lexicon_Project.Interfaces; using CommunityWebsite_Lexicon_Project.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using System.Text.RegularExpressions; using SignInResult = Microsoft.AspNetCore.Identity.SignInResult; namespace CommunityWebsite_Lexicon_Project.Controllers { [ApiController] [Route("[controller]")] public class AccountController : Controller { private readonly UserManager _userManager; private readonly SignInManager _signInManager; private readonly IAccountRepository _accountRepository; public IActionResult Index() { return View(); } public AccountController(IAccountRepository accountRepository) { _accountRepository = accountRepository; } [AllowAnonymous] [HttpGet] public IActionResult Register() { return View(); } [AllowAnonymous] [HttpPost("Register")] public async Task Register(LoginModel submittedAccountModel) { if (ModelState.IsValid) { Account createdUser = new Account() // Create account object. { UserName = submittedAccountModel.Username, Email = submittedAccountModel.Email, }; Regex regex = new Regex(@"^[a-zA-Z0-9]+$"); // Only letters and digits allowed. if (!regex.IsMatch(createdUser.UserName)) { ModelState.AddModelError("NickName", "Only letters and digits are allowed in the NickName field."); } try // Setting the password. { await createdUser.SetPassword(submittedAccountModel.Password); } catch (Exception) { throw new Exception("Error."); } finally // Verify the password. { await createdUser.VerifyPassword(submittedAccountModel.PasswordConfirm); } IdentityResult result = await _userManager.CreateAsync( // Create the Account-Identity object. createdUser, createdUser.PasswordHash ); if (result.Succeeded) { await _accountRepository.AddAsync(createdUser); // Save the Account-Identity object. return RedirectToAction("Login"); //return Ok(); } else { return View(submittedAccountModel); } } else { return BadRequest(); } } [AllowAnonymous] [HttpGet] public IActionResult Login() { return View(); } [AllowAnonymous] [HttpPost("Login")] public async Task Login(LoginModel loginModel) { SignInResult result = await _signInManager.PasswordSignInAsync( loginModel.Username, loginModel.Password, false, false); if (result.IsNotAllowed) { ViewBag.Msg = "Not allowed."; } if (result.IsLockedOut) { ViewBag.Msg = "Account is locked out."; } if (result.Succeeded) { return RedirectToAction("Index", "Home"); } return View(); // ** START OF DATABASE LOGIN ** //Account account = await _accountRepository.GetAccountByUsernameAsync(loginModel.Username); //if (account == null) //{ // return BadRequest(new { message = "No account with that username found." }); //} ////Check if the password is correct ////if (!VerifyPasswordHash(loginModel.Password, account.Password)) //if (!await account.VerifyPassword(loginModel.Password)) //{ // return BadRequest(new { message = "Password is incorrect." }); //} //// Generate a JWT token ////var token = GenerateToken(account); //return Ok(new //{ // Id = account.Id, // UserName = account.UserName, // Email = account.Email, // //Token = token //}); ** END OF DATABASE LOGIN ** } //private bool VerifyPasswordHash(string password, byte[] passwordHash) //{ // using (var hmac = new System.Security.Cryptography.HMACSHA512(passwordHash)) // { // var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); // for (int i = 0; i < computedHash.Length; i++) // { // if (computedHash[i] != passwordHash[i]) return false; // } // } // return true; //} //private string GenerateToken(Account account) //{ // // Your implementation for generating a JWT token goes here //} [HttpGet] public async Task Logout() { await _signInManager.SignOutAsync(); return RedirectToAction("Index", "Home"); } } }