引子

最近在学习IdentityServer4,看了园子里大神们的文章,但是看完之后,能明白这样做可以达到业务需求。但是为什么这样做可以达到业务需求,我用其他方式不行吗?为什么这样做可以呢。也就是老话所说的:

知其然不知其所以然

所以自己看完之后,也看了其他许多教程。总结了.NET Core Identity认证和IdentityServer4的认证框架的知识理论体系,从最开始的基础开始写,会一直写到ASP.NET CORE Identity和IdentityServer结合起来使用。可以帮助园子里新入门的小伙伴们更好的理解ASP.NET CORE Identity和IdentityServer。顺便也是对自己学习完的知识做一个总结。

前提

首先,我们要明白自己做什么,我要要做的是一个登录授权的应用程序。这个程序有什么特点的:就是他可以注册用户,登录用户,判断用户是否有权限访问某某功能,获取这个用户的基本信息等等功能。

首先,在ASP.NET Identity中,认证模块和授权模块是分开的,在.NET Core中,他们也被称为认证中间件和授权中间件。也就是说:当你只做一个模块的时候,可能会出现一个用户她有权限访问某某功能,但是你不知道他是谁(这种情况在代码中是不会出现的,因为会出现异常)。或者说你知道是谁(例如你们公司老板)想访问一下考勤记录功能(需要人力资源权限),但是没做授权,哪怕你知道他是老板,他其实也是无法访问的。

为了更好的让朋友们理解认证和授权,我做了一个Demo,来演示认证(Authentication)和授权(Authorization)  这两个单词长得比较像,注意区分。


本文含有大量GIF图,请耐心等待加载

创建项目

现在我们创建一个空的解决方案,命名解决方案的名称是AspNetCoreIdentity,然后创建一个BasiclyIdentity的项目,最基础的ASP.NET CORE WEB 应用程序。请看GIF图

新建页面

我们创建两个MVC页面,一个是Index主页(不需要授权访问),另外一个是Secert页面(代表着需要授权访问),

右键项目——新建文件夹——创建MVC控制器——HomeController,然后再HomeController里面创建两个接口,分别返回两个页面一个是Index,一个是Secert,代码如下

 using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; namespace BasiclyIdentity.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View("Index");
} [Authorize]
public IActionResult Secert()
{
return View("Secert");
}
}
}

HomeController

 <h1>这是主页,不需要授权访问</h1>

Index.cshtml

 <h1>这需要授权访问的页面</h1>

Secert.cshtml

流程看GIF图

接着,我们试着运行,好像只能返回Hello,world,所以我们需要在StartUp.cs修改一下,因为我们这个空的web应用程序在StartUp.cs默认返回hello,world字符串,代码改成以下内容

 using System;
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.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; namespace BasiclyIdentity
{
public class Startup
{
// 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.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();
} app.UseRouting(); app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}
}

StartUp.cs

演示请看GIF

配置MVC页面

增加授权UseAuthorization

修改完成之后,可以看到可以正确访问页面,至于为什么要改成这样,可以参考构建.NET CORE MVC应用程序教程

接着,我们访问一下授权页面,看下会出现什么情况。

出现了一个错误,错误内容如下:

InvalidOperationException: Endpoint BasiclyIdentity.Controllers.HomeController.Secert (BasiclyIdentity) contains authorization metadata, but a middleware was not found that supports authorization. Configure your application startup by adding app.UseAuthorization() inside the call to Configure(..) in the application startup code. The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...).

从错误异常中微软很贴心的告诉我们要怎么修复这个错误,微软告诉我们需要调用app.UseAuthorization() ,并且这个调用方法要出现在app.UseRouting() and app.UseEndpoints(...).中间

The call to app.UseAuthorization() must appear between app.UseRouting() and app.UseEndpoints(...).

增加认证方案(AuthenticationScheme

修改一下代码,然后访问页面/Home/Secert,同样的,我们会收到以下错误信息

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action<AuthenticationOptions> configureOptions).

大致意思就是没有找到认证方案,也没有找到默认的认证方案。所以我们需要为我们的应用程序配置一个认证方案(authenticationScheme ),所以我们需要添加一个认证方案。

我们添加的认证方案是Cookies认证,即当我们认证的时候,会使用Cookie作为认证手段。在浏览器中插入一条Cookie记录

当需要授权的时候,会去检查浏览器的Cookies,检查一下有没有一个Basicly.Cookies的Cookies

1.如果有就表示通过了授权。即显示Secert页面的内容

2.如果没有,就会跳转到一个默认的登录页,当然,你可以配置登录页。我配置成如果没有登录就跳转到首页。

StartUp.cs

创建登录接口

因为我们上文中没有Cookie所以他跳转到了我们配置的页面,想要访问需要授权的页面,需要有Cookie,那Cookies怎么来呢,所以我们需要新增一个接口,来创建Cookie。

在HomeController下,新增以下代码

 public IActionResult Login()
{
//Claim类似于身份证的某条内容,一条内容对应一条Claim.例如:民族:汉、籍贯:浙江杭州 此处用的是学校的学生证
var schoolClaims = new List<Claim>()
{
new Claim(ClaimTypes.Name,"李雷"),//姓名
new Claim(ClaimTypes.SerialNumber,""),//学号
new Claim("Gender","男"),//性别
}; //Claim类似于身份证的某条内容,一条内容对应一条Claim.例如:民族:汉、籍贯:浙江杭州 此处用的是社会上的驾照
var drivePass =new List<Claim>()
{
new Claim(ClaimTypes.Name,"李雷"),//姓名
new Claim(ClaimTypes.SerialNumber,"浙A00000"),//车牌号
new Claim("Driver","GoodJob"),//开车技术怎么样...随便写的
}; //ClaimsIdentity 类似于身份证、学生证。它是有一条或者多条Claim组合而成。这样就是组成了一个学生证和驾照
var schoolIdentity = new ClaimsIdentity(schoolClaims, "school");
var govIdentity = new ClaimsIdentity(drivePass, "gov"); //claimsPrincipal相当于一个人,你可以指定这个人持有哪些ClaimsIdentity(证件),我指定他持有schoolIdentity、govIdentity那么他就是
//在学校里是学生,在社会上是一名好司机
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(new[] { schoolIdentity, govIdentity }); //HttpContext上下文登录。会根据你在StartUp.cs文件中配置的services.AddAuthentication("CookiesAuth").AddCookie("CookiesAuth")进行操作
//此处就是增加了Cookies
HttpContext.SignInAsync(claimsPrincipal);
//HttpContext上下文登出,会清除Cookies
//HttpContext.SignOutAsync()
return View("Index");
}

然后我们再访问这个接口,可以看到,在我们的浏览器中增加了一个Cookie的一行。按理说,再去访问/home/secert页面总该可以了吧。别急看GIF图

可以看到,增加了Cookies我们还是无法访问Secert页面,为什么呢?回到上文,.net Core Identity分成了授权模块和认证模块,也成为中间件,需要在StartUp.cs里面配置,但是我好像只是用了

所以我们需要额外增加一个

至此,我们可以看看效果怎么样。

非常棒!我们现在已经可以访问授权的页面了。

总结

本章主要介绍了搭建一个MVC页面,怎么使用认证

1.认证(Authentication)和授权(Authorization)——认证(Authentication)是说明你是谁  授权(Authorization)是说明你能干什么

2.声明(Claim)和声明类型(ClaimType)——声明(Claim)是一条记录,声明类型(ClaimType)有默认内置的例如姓名,邮箱,或者自定义性别等字段

3.证件(ClaimsIdentity)和证件持有人(ClaimsPrincipal)——证件(ClaimsIdentity)是由各个机关签发给你的,例如学校签发给你学生证,公安局签发给你身份证,证件持有人(ClaimsPrincipal)则表示你自己,你能持有什么证件

这些都是以后文章的基本知识,希望大家能够多多理解。

问题

1.如果把授权放在前面,认证放在后面会怎么样?

没想到写文章这么累。。。。不懂的地方大家可以在评论区留言

从0开始.NET CORE认证的更多相关文章

  1. asp.net core 认证及简单集群

    众所周知,在Asp.net WebAPI中,认证是通过AuthenticationFilter过滤器实现的,我们通常的做法是自定义AuthenticationFilter,实现认证逻辑,认证通过,继续 ...

  2. ASP.NET Core 认证与授权[2]:Cookie认证

    由于HTTP协议是无状态的,但对于认证来说,必然要通过一种机制来保存用户状态,而最常用,也最简单的就是Cookie了,它由浏览器自动保存并在发送请求时自动附加到请求头中.尽管在现代Web应用中,Coo ...

  3. net core 认证及简单集群

    net core 认证及简单集群 在Asp.net WebAPI中,认证是通过AuthenticationFilter过滤器实现的,我们通常的做法是自定义AuthenticationFilter,实现 ...

  4. centos7.4安装kubernetes1.6.0(开启TLS认证)

    目录 目录 前言 集群详情 环境说明 安装前准备 提醒 一.创建TLS证书和秘钥 安装CFSSL 创建 CA (Certificate Authority) 创建 CA 配置文件 创建 CA 证书签名 ...

  5. .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析

    介绍JwtToken认证之前,必须要掌握.Net Core认证系统的核心原理,如果你还不了解,请参考.Net Core 认证组件源码解析,且必须对jwt有基本的了解,如果不知道,请百度.最重要的是你还 ...

  6. ASP.NET 5 已死 - 隆重介绍 ASP.NET Core 1.0 和 .NET Core 1.0

    还没正式登场就死了?不能怪我标题党,是大神Scott在他博客上这么说的,我只是翻译了一下. 在1月20号最新的ASP.NET Community Standup视频中,微软aspnet开发组的大帅哥 ...

  7. Asp.Net MVC3.0网站统计登录认证的在线人数

    Asp.Net MVC3.0网站统计登录认证的在线人数 前言 对于一个网站来说,统计在线人数是一个很重要的工作.平时也发现很多的网站论坛等都有在线人数的显示.对于一个网站如果在线人数很多,用户看到了这 ...

  8. .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介

    .NET Core 1.0.ASP.NET Core 1.0和EF Core 1.0简介 英文原文:Reintroducing .NET Core 1.0, ASP.NET Core 1.0, and ...

  9. laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证

    第一部分: 安装passport 使⽤ Composer 依赖包管理器安装 Passport : composer require laravel/passport 接下来,将 Passport 的服 ...

随机推荐

  1. LeetCode113 Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...

  2. WPF动画之后属性值无法改变

    原文:WPF动画之后属性值无法改变         前一段时间使用WPF写2048游戏的时候,遇到下面的情形:使用按键对色块进行移动时,触发位置左边X和Y属性的DoubleAnimation动画,但是 ...

  3. Vue.js 第4章 组件与路由

    组件 什么是组件:组件就是一些标签结构的封装,同时为这些结构添加需要的业务逻辑,设置你想要的样式 一个组件中一般可以设置:结构,功能和样式 为什么要使用组件: 使用方便 复用 组件的创建和使用 组件的 ...

  4. oracle函数 SOUNDEX(c1)

    [功能]返回字符串参数的语音表示形式 [参数]c1,字符型 [返回]字符串 [说明]相对于比较一些读音相同,但是拼写不同的单词是非常有用的. 计算语音的算法: 1.保留字符串首字母,但删除a.e.h. ...

  5. 使用HSV色彩空间遮罩绿色区域

    HSV 颜色空间 导入资源 In []: import matplotlib.pyplot as plt import matplotlib.image as mpimg ​ import numpy ...

  6. 利用mock生成随机的东西

    Mock.mock({ "list|100": [ { 'id|+1': 1,//id排列 'color': '@color()',//随机颜色 'date': '@datetim ...

  7. hdu 2807 The Shortest Path(矩阵+floyd)

    The Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. 第二次 C++作业

    1.为什么要用函数? 函数是相对独立的,经常使用的功能抽象化表现形式,函数的优势在于,编写之后可以被重复使用,使用时可以只关心函数的功能和使用方法而不必关心函数的具体实现,这样可以有利于代码重用,可以 ...

  9. HTML静态网页--JavaScript-语法

    1.基本数据类型: 字符串.小数.整数.日期时间.布尔型等. 2.变量: 都是通用类型var,可以随便存储其他类型的值,可以直接使用,不用定义,但习惯上定义.定义变量:var a:所有变量定义 都用v ...

  10. mac常用快捷键,Mac文件重命名快捷键,Mac OS快速访问系统根目录, MacOS 10.11重要数据的存储位置大全

    command+r,相当于F5,刷新页面 command+F5,启动voiceover command+q 关闭当前程序 在Finder中command+/ 打开底部状态栏,可以查看剩余磁盘空间大小 ...