原文:ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程

ASP.NET Core Identity 配置

上一章节我们简单介绍了下 Identity 框架中的 [Authorize][AllowAnonymous],但在章节的末尾,我一直费解的是为什么不是提示 401 未授权而是报错

后来我想了想,想了想,终于想起来了,我们在创建 HelloWorld 项目的时候没有勾选验证用户选项

如果你的电脑是 Windows,是否还记得下面这张图

对,我们选择的就是 不进行身份验证

哎,早知如此,何必当初,算了,算了,我们想一些办法进行补救吧。

如果你使用 Visual Studio 创建一个新的 ASP.NET Core 应用程序时,如果设置了身份验证。那么就可以跳过接下来的设置了。

不过呢,我建议你继续往下学习,说不定,哪天,用得着呢

本章节,我们将学习如何安装和配置 Identity 框架,其实只要做一点点的配置

配置 Identity 事项

因为我们的 HelloWorld 是从一个空的项目模板开始的,所以我们将头开始配置 Identity 框架,这也是了解和学习其它项目模板的最好的方法,如果我们没有仔细研究各种配置,那么可能会产生很多困惑

首先,我们要安装两个依赖项目 Microsoft.AspNetCore.IdentityMicrosoft.AspNetCore.Identity.EntityFramework,前者一般情况下都内置了,后者会随着安装 Entity Frawework 一起安装

如果你在依赖项里没有找到它们,那就使用 NuGet 安装呗,反正装起来也不麻烦

对了,忘记说了,因为你的项目可能不使用 Entity Frawework,那么可以单独安装 Microsoft.AspNetCore.Identity.EntityFramework

当这两个依赖项安装完成后,我们就可以创建一个用户类,用于包含我们想要存储的有关用户的所有信息

对于我们的应用程序,我们将继承 Identity 框架提供的基类,使用该类提供所有基本要素,如用户名属性和存储散列密码

我们也会修改 HelloWorldDBContext 类继承自 Identity 框架的 IdentityDb 类而非 Microsoft.EntityFrameworkCore 命名空间下的 DbContextIdentityDb 类提供了 EF 框架存储用户信息所需的所有东西

一旦我们设置好了 User 类和 DBContext,接着就需要在 Startup 类的 ConfigureServices 方法中添加 Identity 服务,就像使用 MVC 时需要添加服务一样,使用 Identity 时也需要添加服务

我们需要注册的 Identity 服务有两项:UserStore 服务和 SignInManager 服务,这些服务会在需要的时候注入我们的控制器,以便在需要的时候创建用户和发送 cookies

最后,还需要在 Startup 类中的 Configure 方法中添加中间件 Identity,这个中间件可以读取 cookie 信息并创建用户身份,而且可以保证未授权时返回的是一个普通的页面和不适 401 空白页面

配置 Identity

刚刚,我们已经把配置 Identity 需要做的事情了解清楚了,接下来我们就一步一步来实现吧

  1. 安装依赖 Microsoft.AspNetCore.IdentityMicrosoft.AspNetCore.Identity.EntityFramework,这个就不多讲了,忽略

  2. Models 目录下添加一个用户类 User,添加过程也不详细介绍了,添加完成后默认的代码如下

    using System;
    namespace HelloWorld.Models
    {
    public class User
    {
    public User()
    {
    }
    }
    }
  3. 修改 User.cs 引入命名空间 Microsoft.AspNetCore.Identity,并修改 User 类继承自 IdentityUser,修改完成后 User.cs 代码如下

    using System;
    
    using Microsoft.AspNetCore.Identity;
    
    namespace HelloWorld.Models
    {
    public class User: IdentityUser
    {
    public User()
    {
    }
    }
    }
  4. 我们近距离观察下 IdentityUser ,将鼠标指针移到 IdentityUser 上,然后按 F12 ( windows ) 或 COMMAND + D ( macOS ),可以跳转到 IdentityUser 的元数据界面,显示如下

    为了方便查看,我们删除了原来代码中的所有注释

    using System;
    
    namespace Microsoft.AspNetCore.Identity
    {
    public class IdentityUser : IdentityUser<string>
    {
    public IdentityUser ();public IdentityUser (string userName): this ();
    }
    }

    我们可以看到 IdentityUser 继承自接收一个字符串范型的 IdentityUser,它使用用户名作为唯一标识

    所以,我们也可以自定义个一个 IdentityUser 继承自接收一个整型 ( int ) 范型的 IdentityUser,可以使用 ID 作为唯一标识

  5. 我们可以将鼠标移动到 IdentityUser<string> 上,然后按 F12 ( windows ) 或直接点击它可以跳转到 IdentityUser<TKey> 的元数据界面,显示如下

    为了方便查看,我们删除了原来代码中的所有注释

    using System;
    using System.Runtime.CompilerServices; namespace Microsoft.AspNetCore.Identity
    {
    public class IdentityUser<TKey> where TKey : IEquatable
    {
    public virtual TKey Id {get;set;}
    public virtual string UserName {get;set;}
    public virtual string NormalizedUserName {get;set;}
    public virtual string Email {get;set;}
    public virtual string NormalizedEmail {get;set;}
    public virtual bool EmailConfirmed {get;set;}
    public virtual string PasswordHash {get;set;}
    public virtual string SecurityStamp {get;set;}
    public virtual string ConcurrencyStamp {get;set;} = ((object)Guid.NewGuid ()).ToString ();
    public virtual string PhoneNumber {get;set;}
    public virtual bool PhoneNumberConfirmed {get;set;}
    public virtual bool TwoFactorEnabled {get;set;}
    public virtual DateTimeOffset? LockoutEnd {get;set;}
    public virtual bool LockoutEnabled {get;set;}
    public virtual int AccessFailedCount {get;set;} public IdentityUser ();
    public IdentityUser (string userName): this (); public override string ToString ();
    }
    }

    我们可以看到默认的与用户相关的所有信息,包括

    1. 可以使用,但在我们的 HelloWorld 项目中并不会使用的字段
    2. Identity 框架可以跟踪用户失败的登录尝试次数,并可锁定该帐户一段时间
    3. 用于存储 PasswordHash 和 PhoneNumber 的字段,我们最感兴趣的莫过于 PasswordHash 和 UserName
    4. 我们也会隐式地使用用户主键和 ID 属性,主要用于查询指定用户
  6. 经过近距离观察了上面两个类和结构,我们知道了我们的 User 类的一些信息,接下来我们需要确保 HelloWorldDBContext 包含了 User 类。

    双击打开 HelloWorldDBContext.cs,修改 HelloWorldDBContext 继承自 IdentityDbContext 而不是 DBContext

    为了使用 IdentityDbContext,我们需要引入命名空间 Microsoft.AspNetCore.Identity.EntityFrameworkCore

    修改完成后,HelloWorldDBContext.cs 代码如下

    using System;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore; namespace HelloWorld.Models
    {
    public class HelloWorldDBContext:IdentityDbContext<User>
    {
    public HelloWorldDBContext(){} public HelloWorldDBContext(DbContextOptions<HelloWorldDBContext> options)
    : base(options)
    { }
    public DbSet<Employee> Employees { get; set; }
    }
    }
  7. 因为 IdentityDbContext 位于命名空间 Microsoft.AspNetCore.Identity.EntityFrameworkCore 下,所以我们给 User 添加的任何额外的属性都会保存到数据库中

    IdentityDbContext 自带了 DbSets,这不仅用于存储用户,还提供了有关用户角色和用户声明的信息

  8. User 类基本就这样了,我们也不再添加额外信息,而且也成功配置了 HelloWorldDBContext 使用 Identity 框架,接下来是时候在 Startup 类中的 ConfigureConfigureServices 两个方法中配置 Identity 框架

  9. 首先我们要配置的是 ConfigureServices() 方法,需要添加 Identity 服务和所有依赖的相关服务

    public void ConfigureServices(IServiceCollection services)
    {
    services.AddMvc(); services.AddEntityFrameworkSqlite().AddDbContext<HelloWorldDBContext>(options => options.UseSqlite(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>().AddEntityFrameworkStores<HelloWorldDBContext>(); }

    AddIdentity() 方法需要传递两个范型参数: 用户实体的类型和角色实体的类型,这两个范型类型分别是我们刚刚创建的 User 类和一个用户角色类,我们默认使用 Microsoft.AspNetCore.Identity 命名空间下的 IdentityRole

    所以为了使用 IdentityRole 类,我们需要引入命名空间 Microsoft.AspNetCore.Identity;

    为了在 Identity 框架中使用 EF 框架,我们需要使用 AddEntityFrameworkStores() 方法来使用 EF 框架存储数据,AddEntityFrameworkStores() 会自动配置 UserStore 这样的服务,用于创建用户和验证其密码

  10. 接下来是配置 Identity 中间件

    插入 Identity 中间件的位置非常重要,如果在管道中插入中间件的时间太晚,它将永远没有机会处理请求

    但如果要在 MVC 控制器中进行授权检查,又需要在 MVC 框架之前插入 Identity 中间件,以确保 cookie 和 401 错误得到成功处理

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    } app.UseFileServer(); app.UseAuthentication(); app.UseMvc(ConfigureRoute); }

配置完成后,我们的 Startup.cs 中的完整代码如下

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using HelloWorld.Models; namespace HelloWorld
{
public class Startup
{
public Startup()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("AppSettings.json");
Configuration = builder.Build();
} public IConfiguration Configuration { get; set; } // This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); services.AddEntityFrameworkSqlite().AddDbContext<HelloWorldDBContext>(options => options.UseSqlite(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>().AddEntityFrameworkStores<HelloWorldDBContext>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseFileServer(); app.UseAuthentication(); app.UseMvc(ConfigureRoute); } private void ConfigureRoute(IRouteBuilder routeBuilder)
{
//Home/Index
routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}");
}
}
}

重启应用程序,刷新浏览器,可以看到访问任何一个员工的详情页面时会提示跳转到一个登录界面

当然,目前这个登录我们还没实现,等到下一章节吧

好累,这一章节总算完成了

不知大家有没有发现,我们用了这么大的篇幅讲了这么多内容,可真正写的代码不超过 50 行

ASP.NET Core Identity 配置 - ASP.NET Core 基础教程 - 简单教程,简单编程的更多相关文章

  1. ASP.NET Core Identity 框架 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Identity 框架 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 框架 前面我们使用了 N 多个章节, ...

  2. Net Core Identity 身份验证:注册、登录和注销 (简单示例)

    一.前言 一般我们自己的系统都会用自己设置的一套身份验证授权的代码,这次用net core的identity来完成简单的注册.登录和注销. 二.数据库 首先就是创建上下文,我这里简单的建了Users和 ...

  3. Asp.Net Core Identity 隐私数据保护

    前言 Asp.Net Core Identity 是 Asp.Net Core 的重要组成部分,他为 Asp.Net Core 甚至其他 .Net Core 应用程序提供了一个简单易用且易于扩展的基础 ...

  4. 从零搭建一个IdentityServer——集成Asp.net core Identity

    前面的文章使用Asp.net core 5.0以及IdentityServer4搭建了一个基础的验证服务器,并实现了基于客户端证书的Oauth2.0授权流程,以及通过access token访问被保护 ...

  5. 普通用户su 到root,无需密码方式,及iptables封掉本机某个端口,core文件配置

    一. 普通用户su到root无需密码: 随着服务器越来越多,普通用户转到root下,去查密码表是个很繁琐的事,发现有如下方式比较方便(需要root操作) vi /etc/pam.d/su  将 aut ...

  6. IdentityServer(12)- 使用 ASP.NET Core Identity

    IdentityServer具有非常好的扩展性,其中用户及其数据(包括密码)部分你可以使用任何想要的数据库进行持久化. 如果需要一个新的用户数据库,那么ASP.NET Core Identity是你的 ...

  7. ASP.NET Core Identity Hands On(2)——注册、登录、Claim

    上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...

  8. ASP.NET Core 项目配置 ( Startup )(转载)

    原文:https://www.twle.cn/l/yufei/aspnetcore/dotnet-aspnet-startup.html 由于是个人网站,怕没了,特意复制保存,个人觉得讲的非常透彻 前 ...

  9. 第16章 使用ASP.NET Core Identity - Identity Server 4 中文文档(v1.0.0)

    注意 对于任何先决条件(例如模板),首先要查看概述. IdentityServer旨在提供灵活性,其中一部分允许您为用户及其数据(包括账户密码)使用所需的任何数据库.如果您从新的用户数据库开始,那么A ...

随机推荐

  1. windows关闭进程 批处理端口占用

    cmd 关闭进程java taskkill /F /IM java.exe taskkill /f /im java.exe 如何用dat批处理文件关闭某端口对应程序-Windows自动化命令 如何用 ...

  2. leetcode笔记:Remove Duplicates from Sorted Array II

    一.题目描写叙述 二.解题技巧 这道题和Remove Duplicates from Sorted Array这道题是相似的.仅仅只是这里同意出现反复的数字而已,能够採用二分搜索的变种算法.仅仅只是增 ...

  3. php 文件夹是否存在,不存在就创建

    $lujing = "./nihao/wohao"; if(!is_dir($liujing)){ mkdir(iconv("UTF-8", "GBK ...

  4. ng-cli搭建angular项目框架

    原文地址 https://www.jianshu.com/p/0a8f4b0f29b3 环境准备 以下步骤都不需要事先创建文件夹,只是环境的准备过程,只有到需要搭建项目的时候才需要创建文件夹用来存放项 ...

  5. java数组10大技巧

    0.  声明一个数组(Declare an array) String[] aArray = new String[5]; String[] bArray = {"a"," ...

  6. opencv和linux的关联

    这是一篇关于opencv和linux关联的文章

  7. 【C++竞赛 E】xxx和yyy的旅行

    时间限制:1s 内存限制:32MB 问题描述 有n个城市和m条双向铁路.对于任意两个不同的城市x和城市y,两个城市之间有双向铁路,否则有双向公路,通过任意一条直达公(铁)路花费一小时.城市x与城市y存 ...

  8. SNMP 配置

    http://blog.sina.com.cn/s/blog_593bf1da0100xsvu.html

  9. Django + Apache + wsgi配置和环境搭建(ubuntu)

    上一篇写了Django + nginx + uwsgi配置和环境搭建(ubuntu) 由于公司服务器环境问题,又配置了apache的环境.记录例如以下: 一. 安装环境: #apache sudo a ...

  10. tcp长连接和短连接

    tcp长连接和短连接 TCP在真正的读写操作之前,server与client之间必须建立一个连接, 当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接, 连接的建立通过三次握手,释放则需要四 ...