引子

最近在学习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. 大侦探福老师——幽灵Crash谜踪案

    闲鱼Flutter技术的基础设施已基本趋于稳定,就在我们准备松口气的时候,一个Crash却异军突起冲击着我们的稳定性防线!闲鱼技术火速成立侦探小组执行嫌犯侦查行动,经理重重磨难终于在一个隐蔽的角落将其 ...

  2. 《C语言深度解剖》学习笔记之符号

    第2章 符号 1.注释符号 编译器会将注释剔除,用空格代替原来的注释 y=x /* p; 编译器提示出错的原因:实际上,编译器会把“/*”当作一段注释的开始,直到出现“*/”为止. [规则 2-1]注 ...

  3. 修改Mariadb存储路径

    大部分基于此文章操作:http://lddyw.blog.51cto.com/4151746/1684364 找个好久的资料,都打算源码安装了,最后终于更改成功了. 环境:CentOS6.6 64位虚 ...

  4. git学习一——Pro-Git

    1.配置用户名,邮箱 git config --global user.name "Mike" git config --global user.email Mike@exampl ...

  5. python基础之逻辑题(1)

    python基础之逻辑题(1) 1.用一行代码实现数值交换? 2.求结果--fromkeys? 3.1,2,3,4,5能组成多少个互不相同且无重复的三位数? 4.有两个字符串列表a和b,每个字符串是逗 ...

  6. autocomplete="off" inpu属性

    input 的属性autocomplete 默认为on 其含义代表是否让浏览器自动记录之前输入的值 很多时候,需要对客户的资料进行保密,防止浏览器软件或者恶意插件获取到 可以在input中加入auto ...

  7. NLP进阶之(七)膨胀卷积神经网络

    NLP进阶之(七)膨胀卷积神经网络1. Dilated Convolutions 膨胀卷积神经网络1.2 动态理解1.2.2 转置卷积动画1.2.3 理解2. Dilated Convolutions ...

  8. java面向接口编程之制定标准和简单工厂模式

    制定一个标准,让别人去实现或者说满足它! Eg: interface USB{//定义USB标准 void useUSB();//USB有使用USB的行为 } 简单工厂模式 构建一个工厂出来,在里面进 ...

  9. Python 基础课程大纲

      c0102_变量及数据类型.ipynb 1.数据类型概述 Python标准数据类型:Numbers数字,String字符串,List列表,Tuple元祖,Dici字典.布尔类型 # Numbers ...

  10. SpringBoot2.0 使用AOP统一处理Web请求日志(完整版)

    一,加入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...