目錄
介紹
身份驗證是根據系統或用戶的身份確定或給予其個人訪問權限的過程。.NET Core中有多個選項可以進行身份驗證。本文演示瞭如何使用內存數據庫在.NET Core 3.0中添加基於身份(Identity-Based)的身份驗證。
背景
在上一篇文章中,我介紹了.NET Core 3.0中的Cookie身份驗證。
先決條件
創建Web應用程序的步驟
1、轉到Visual Studio 2019,然後選擇從選項列表中創建新項目。
2、選擇後,將打開一個新窗口以選擇項目模板。
3、選擇“ASP.NET Core Web應用程序”,然後單擊“下一步”按鈕。
4、將打開一個新屏幕,以配置新項目。根據您的要求提供項目名稱,位置,解決方案名稱。按創建按鈕。
5、單擊“創建”按鈕後,將打開一個新屏幕以配置與項目相關的信息,例如您要爲Web應用程序創建哪種環境?.NET Framework或.NET Core。從下拉列表中選擇.NET Core和ASP.NET Core版本。然後,從列表中選擇Web應用程序(模型-視圖-控制器)選項,然後按創建按鈕創建一個項目。
6、現在,我們的項目將以.NET Core環境的基本結構打開。您可以在解決方案資源管理器中觀察到,其中將包含帶有“Startup.cs”的Controllers,Models 和Views 文件夾以及其他文件,如下圖所示:
7、運行您的應用程序,以檢查創建的Web應用程序是否運行正常。默認情況下,它將打開您的項目的主頁(Home控制器的Index頁)。
安裝以下3.0.0版本或最新版本的NuGet
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.InMemo
- Microsoft.EntityFrameworkCore.Identity.EntityFrameworkCore
集成身份認證
- IdentityDbContext:提供管理身份表所需的所有DbSet屬性
- ApplicationDbContext:用戶定義的DbContext類繼承自IdentityDbContext類以管理用戶身份
- UseInMemoryDatabase:將用於標識的用戶信息存儲在內存中,而不使用任何數據庫
- AppUser:用戶定義的類繼承自IdentityUser,以添加用戶的其他屬性
- UserManager:要管理用戶信息(如創建用戶信息),請刪除用戶信息
- SignInManager:通過HttpContext處理通訊以及用戶登錄或註銷功能
- [Authorize]:屬性有助於驗證訪問控制器的用戶(用戶信息)
第1步
創建一個名爲Data的新文件夾並添加ApplicationDbContext 到其中,並將以下代碼行放入其中:
using DemoIdentityAuthentication.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace DemoIdentityAuthentication.Data
{
// IdentityDbContext contains all the user tables
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
}
第2步
使用名稱AppUser將新類添加到Models文件夾中, 並將以下代碼行放入其中:
using Microsoft.AspNetCore.Identity;
namespace DemoIdentityAuthentication.Models
{
public class AppUser : IdentityUser
{
public string Name { get; set; }
public string DateOfBirth { get; set; }
public string Password { get; set; }
}
}
第3步
Startup.cs文件中的更改:
using DemoIdentityAuthentication.Data;
using DemoIdentityAuthentication.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
namespace DemoIdentityAuthentication
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(config =>
{
// for in memory database
config.UseInMemoryDatabase("MemoryBaseDataBase");
});
// AddIdentity :- Registers the services
services.AddIdentity<AppUser, IdentityRole>(config =>
{
// User defined password policy settings.
config.Password.RequiredLength = 4;
config.Password.RequireDigit = false;
config.Password.RequireNonAlphanumeric = false;
config.Password.RequireUppercase = false;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Cookie settings
services.ConfigureApplicationCookie(config =>
{
config.Cookie.Name = "DemoProjectCookie";
config.LoginPath = "/Home/Login"; // User defined login path
config.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
services.AddControllersWithViews();
}
// This method gets called by the runtime.
// Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/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.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
第4步
使用新的操作方法進行更新HomeController:
- 登錄名:用於用戶登錄
- 註冊:用於註冊新用戶
- 註銷:註銷當前用戶
- 帶有Authorize標籤的UserInfo:顯示有效用戶的用戶信息,並限制獲取無效用戶的訪問權限
將以下代碼行放入HomeController:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using DemoIdentityAuthentication.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Authorization;
namespace DemoIdentityAuthentication.Controllers
{
public class HomeController : Controller
{
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
public HomeController(
UserManager<AppUser> userManager,
SignInManager<AppUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
public IActionResult Index()
{
return View();
}
[Authorize]
public async Task<IActionResult> UserInfo()
{
var user =
await _userManager.GetUserAsync(HttpContext.User).ConfigureAwait(false);
if (user == null)
{
RedirectToAction("Login");
}
//login functionality
return View(user);
}
[HttpGet]
public IActionResult Login()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Login(AppUser appUser)
{
//login functionality
var user = await _userManager.FindByNameAsync(appUser.UserName);
if (user != null)
{
//sign in
var signInResult = await _signInManager.PasswordSignInAsync
(user, appUser.Password, false, false);
if (signInResult.Succeeded)
{
return RedirectToAction("Index");
}
}
return RedirectToAction("Register");
}
public IActionResult Register()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Register(AppUser appUser)
{
//register functionality
var user = new AppUser
{
Id = "101",
UserName = appUser.UserName,
Email = appUser.Email,
Name = appUser.Name,
DateOfBirth = appUser.DateOfBirth,
Password = appUser.Password
};
var result = await _userManager.CreateAsync(user, user.Password);
if (result.Succeeded)
{
// User sign
// sign in
var signInResult = await _signInManager.PasswordSignInAsync
(user, user.Password, false, false);
if (signInResult.Succeeded)
{
return RedirectToAction("Index");
}
}
return View();
}
public async Task<IActionResult> LogOut(string username, string password)
{
await _signInManager.SignOutAsync();
return RedirectToAction("Index");
}
}
}
第5步
爲HomeController添加view :
1、轉到Views文件夾,然後選擇“Home文件夾”。
2、右鍵單擊Home文件夾以選擇添加選項,然後選擇視圖。
3、將打開一個彈出窗口以添加視圖。
4、提供“視圖名稱”爲Login,選擇“模板”爲Empty,選擇“使用佈局頁面”,然後按“添加”按鈕。一個新的Login.cshtml文件將創建到Home文件夾中。請參考下圖添加視圖:
5、對於其他視圖,請遵循相同的步驟,併爲UserInfo 操作和Register 操作創建視圖。
6、Login.cshtml 頁面的代碼:
@model DemoIdentityAuthentication.Models.AppUser
<h1>User Login</h1>
<form asp-controller="Home" asp-action="Login">
<div class="form-group col-sm-6">
<label for="Username">Username</label>
<input type="text" class="form-control"
id="Username" asp-for="UserName"
placeholder="Enter username">
</div>
<div class="form-group col-sm-6">
<label for="Password">Password</label>
<input type="password" class="form-control" id="Password"
asp-for="Password" placeholder="Enter password">
</div>
<div class="form-group col-sm-6">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form>
@model DemoIdentityAuthentication.Models.AppUser
@{
ViewData["Title"] = "Register";
}
<h1>User Register</h1>
<form method="post" asp-controller="Home" asp-action="Register">
<div class="form-group col-sm-6">
<label for="Name">Name</label>
<input type="text" class="form-control"
id="Name" asp-for="Name" placeholder="Enter name">
</div>
<div class="form-group col-sm-6">
<label for="EmailId">Email Id</label>
<input type="email" class="form-control"
id="EmailId" asp-for="Email" placeholder="Enter email id">
</div>
<div class="form-group col-sm-6">
<label for="Username">Username</label>
<input type="text" class="form-control"
id="Username" asp-for="UserName" placeholder="Enter username">
</div>
<div class="form-group col-sm-6">
<label for="Password">Password</label>
<input type="password" class="form-control"
id="Password" asp-for="Password" placeholder="Enter password">
</div>
<div class="form-group col-sm-6">
<label for="DOB">Date Of Birth</label>
<input type="text" class="form-control"
id="DOB" asp-for="DateOfBirth" placeholder="Enter date of birth">
</div>
<div class="form-group col-sm-6">
<button type="submit" class="btn btn-primary">Register</button>
</div>
</form>
7、UserInfo.cshtml頁面的代碼:
@model DemoIdentityAuthentication.Models.AppUser
<h1>User Information</h1>
<table>
<tr>
<td>Name:- </td>
<td>@Html.DisplayFor(model => model.Name)</td>
</tr>
<tr>
<td>Email:- </td>
<td>@Html.DisplayFor(model => model.Email)</td>
</tr>
<tr>
<td>Username:- </td>
<td>@Html.DisplayFor(model => model.UserName)</td>
</tr>
<tr>
<td>Date Of Birth:- </td>
<td>@Html.DisplayFor(model => model.DateOfBirth)</td>
</tr>
</table>
第6步
更新_Layout.cshtml 頁面以添加用於用戶登錄、用戶註冊、用戶信息和用戶註銷的新選項卡/超鏈接。
_Layout.cshtml的代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - DemoIdentityAuthentication</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm
navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area=""
asp-controller="Home"
asp-action="Index">DemoIdentityAuthentication</a>
<button class="navbar-toggler" type="button"
data-toggle="collapse" data-target=".navbar-collapse"
aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area=""
asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area=""
asp-controller="Home" asp-action="Register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area=""
asp-controller="Home" asp-action="Login">Login</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area=""
asp-controller="Home"
asp-action="UserInfo">User Information</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area=""
asp-controller="Home" asp-action="Logout">Logout</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2020 - DemoIdentityAuthentication - <a asp-area=""
asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
運行您的應用程序
成功運行應用程序後,應用程序的輸出應類似於以下屏幕:
1、單擊“用戶信息”選項卡以獲取當前的登錄用戶信息,它將打開一個登錄頁面以登錄用戶。
問題:爲什麼會要求登錄?
答:[Authorize]屬性限制訪問未經授權的請求的數據/信息,並重定向到登錄頁面以檢查用戶是否有效。在我們的示例中,我們在HomeController的UserInformation操作方法上添加了此屬性。
2、在登錄之前註冊您的帳戶。單擊註冊選項卡,然後根據以下屏幕提供用戶信息:
3、成功註冊後,它將在瀏覽器中創建一個cookie,如下所示:
4、現在,單擊“登錄”選項卡,然後輸入用戶名和密碼,如以下屏幕所示:
再次單擊UserInformation選項卡,現在您無需登錄即可查找用戶信息的最終結果。
總結
在本文中,我討論瞭如何使用內存數據庫在.NET Core 3.0中添加基於身份的身份驗證。我們還創建了用戶登錄和註冊表單,以使用戶登錄到我們的應用程序以訪問有用的信息。我希望這將有助於讀者理解如何在任何應用程序中實現基於身份的身份驗證。請找到隨附的代碼以更好地理解。