目录
介绍
身份验证是根据系统或用户的身份确定或给予其个人访问权限的过程。.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中添加基于身份的身份验证。我们还创建了用户登录和注册表单,以使用户登录到我们的应用程序以访问有用的信息。我希望这将有助于读者理解如何在任何应用程序中实现基于身份的身份验证。请找到随附的代码以更好地理解。