【從0開始.NET CORE認證】-1 認識認證和授權


引子

最近在學習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,代碼如下

 1 using Microsoft.AspNetCore.Authorization;
 2 using Microsoft.AspNetCore.Mvc;
 3 
 4 namespace BasiclyIdentity.Controllers
 5 {
 6     public class HomeController : Controller
 7     {
 8         public IActionResult Index()
 9         {
10             return View("Index");
11         }
12 
13         [Authorize]
14         public IActionResult Secert()
15         {
16             return View("Secert");
17         }
18     }
19 }
HomeController
1 <h1>這是主頁,不需要授權訪問</h1>
Index.cshtml
1 <h1>這需要授權訪問的頁面</h1>
Secert.cshtml

流程看GIF圖

接着,我們試着運行,好像只能返回Hello,world,所以我們需要在StartUp.cs修改一下,因為我們這個空的web應用程序在StartUp.cs默認返回hello,world字符串,代碼改成以下內容

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Threading.Tasks;
 5 using Microsoft.AspNetCore.Builder;
 6 using Microsoft.AspNetCore.Hosting;
 7 using Microsoft.AspNetCore.Http;
 8 using Microsoft.Extensions.DependencyInjection;
 9 using Microsoft.Extensions.Hosting;
10 
11 namespace BasiclyIdentity
12 {
13     public class Startup
14     {
15         // This method gets called by the runtime. Use this method to add services to the container.
16         // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
17         public void ConfigureServices(IServiceCollection services)
18         {
19             services.AddControllersWithViews();
20         }
21 
22         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
23         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
24         {
25             if (env.IsDevelopment())
26             {
27                 app.UseDeveloperExceptionPage();
28             }
29 
30             app.UseRouting();
31 
32             app.UseEndpoints(endpoints =>
33             {
34                 endpoints.MapDefaultControllerRoute();
35             });
36         }
37     }
38 }
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下,新增以下代碼

 1 public IActionResult Login()
 2         {
 3             //Claim類似於身份證的某條內容,一條內容對應一條Claim.例如:民族:漢、籍貫:浙江杭州 此處用的是學校的學生證
 4             var schoolClaims = new List<Claim>()
 5             {
 6                 new Claim(ClaimTypes.Name,"李雷"),//姓名
 7                 new Claim(ClaimTypes.SerialNumber,"0001"),//學號
 8                 new Claim("Gender",""),//性別
 9             };
10 
11             //Claim類似於身份證的某條內容,一條內容對應一條Claim.例如:民族:漢、籍貫:浙江杭州 此處用的是社會上的駕照
12             var drivePass =new List<Claim>()
13             {
14                 new Claim(ClaimTypes.Name,"李雷"),//姓名
15                 new Claim(ClaimTypes.SerialNumber,"浙A00000"),//車牌號
16                 new Claim("Driver","GoodJob"),//開車技術怎么樣...隨便寫的
17             };
18 
19             //ClaimsIdentity 類似於身份證、學生證。它是有一條或者多條Claim組合而成。這樣就是組成了一個學生證和駕照
20             var schoolIdentity = new ClaimsIdentity(schoolClaims, "school");
21             var govIdentity = new ClaimsIdentity(drivePass, "gov");
22 
23             //claimsPrincipal相當於一個人,你可以指定這個人持有哪些ClaimsIdentity(證件),我指定他持有schoolIdentity、govIdentity那么他就是
24             //在學校里是學生,在社會上是一名好司機
25             ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(new[] { schoolIdentity, govIdentity });
26 
27             //HttpContext上下文登錄。會根據你在StartUp.cs文件中配置的services.AddAuthentication("CookiesAuth").AddCookie("CookiesAuth")進行操作
28             //此處就是增加了Cookies
29             HttpContext.SignInAsync(claimsPrincipal);
30             //HttpContext上下文登出,會清除Cookies
31             //HttpContext.SignOutAsync()
32             return View("Index");
33         }

 

然后我們再訪問這個接口,可以看到,在我們的瀏覽器中增加了一個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.如果把授權放在前面,認證放在后面會怎么樣?

沒想到寫文章這么累。。。。不懂的地方大家可以在評論區留言


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM