.NET Core中的認證管理解析

来源:http://www.cnblogs.com/durow/archive/2016/08/18/5783089.html
-Advertisement-
Play Games

.NET Core中的認證管理解析 0x00 問題來源 在新建.NET Core的Web項目時選擇“使用個人用戶賬戶”就可以創建一個帶有用戶和許可權管理的項目,已經準備好了用戶註冊、登錄等很多頁面,也可以使用AuthorizeAttribute進行各種許可權管理,看起來似乎十分方便。不過生成的代碼都替我 ...


.NET Core中的認證管理解析

 

0x00 問題來源

在新建.NET Core的Web項目時選擇“使用個人用戶賬戶”就可以創建一個帶有用戶和許可權管理的項目,已經準備好了用戶註冊、登錄等很多頁面,也可以使用AuthorizeAttribute進行各種許可權管理,看起來似乎十分方便。不過生成的代碼都替我幹了些什麼我一團霧水。看了下生成的數據表,功能也挺複雜的。實際上我需要的只是基於用戶和角色的認證管理,而且用戶資料是使用現有的庫,但使用.NET Core自帶的認證組件必須要依賴EF,表的結構也很多對不上,所以學習了下自帶的認證組件的實現,然後自己寫了個認證服務替換了Identity組件,同時Cookie管理使用自帶的Cookie中間件、可以使用AuthorizeAttribute進行認證。複雜的需求還沒遇到,所以就學習到了這裡。這篇博客主要討論最簡單情況下的的基於用戶和角色的認證。關於.NET Core自帶認證組件的一些基本用法,可以參考https://docs.asp.net/en/latest/security/authentication/accconfirm.html

0x01 .NET Core中的認證管理

提到認證管理,首相想到的就是用戶的註冊、登錄、註銷以及給用戶添加/刪除角色等功能。其中用戶信息,角色信息等都是保存在資料庫中的。所以主要包含資料庫操作和登錄業務邏輯兩部分。在登錄業務邏輯層面,.NET Core主要通過三個比較核心的類UserManager、RoleManager、SigninManager進行管理(在Microsoft.AspNetCore.Identity程式集)。其中:

  • UserManager主要負責用戶的認證、註冊、修改、刪除以及與用戶相關的角色、令牌、聲明等的管理。
  • RoleManager負責角色、角色相關聲明的管理。
  • SigninManager負責登錄、註銷等相關操作。在涉及到用戶操作(如登陸時用戶驗證)會調用UserManager進行操作。

這三個核心類在操作資料庫時,使用資料庫層面的UserStore、RoleStore進行操作(在Microsoft.AspNetCore.Identity.EntityFrameworkCore程式集)。業務關係如下圖所示:

 

我們在開發認證相關功能時使用這三個核心類即可滿足大多數需求。我們在使用這幾個核心類的對象時都是通過依賴註入獲取的,那麼這些相關的依賴是什麼時候註入的呢?在Startup的ConfigureServices方法中有AddIdentity擴展方法,就是在這個方法中添加了需要的所有依賴。

0x02 登錄和註銷

瞭解了Identity組件的整體分工後,再來看一下登錄和註銷的操作的部分細節。登錄和註銷過程主要由SigninManager負責,的先來看一下登錄的過程:

 

登錄成功後Response的Header中包含了Set-Cookie,Cookie的Key需要和Cookie中間件中設置的要解密的Cookie的Key一致,在截圖中這個Cookie的Key是IdentityCookie。設置Cookie的同時返回302重定向到登錄頁面。

 

重定向到登陸頁面時,請求中已經帶有設置的Key為IdentityCookie的Cookie了。

 

註銷過程比較簡單,調用HttpContext.Authentication.SignOutAsync方法即可註銷,此時會給HttpContext.Response添加Set-Cookie,但內容為空。

0x03 通過Cookie識別用戶

.NET Core中通過CookieAuthenticationMiddleware這個中間件識別HttpContext中認證相關的Cookie,從而添加用戶的驗證和授權信息。最關鍵的是ClaimsPrincipal對象,它記錄用戶的認證和授權信息(除此之外當然也可以包含其它你需求的任意信息),從上面登錄過程可以看到,登錄成功後用戶認證和授權信息保存至ClaimsPrincipal對象(實際上對於這條Cookie鍵值對中的認證信息保存為ClaimsIdentity,一個ClaimsPrincipal可以包含多個ClaimsIdentity),然後在HttpContext.Response的Headers中添加Set-Cookie,Key為Cookie中間件中指定的CookieName,Value就是這個對象加密後的字元串。以後的HttpContext都會帶有這個Cookie,Cookie中間件會把符合這個CookieName的Cookie取出來,解密並還原為ClaimsPrincipal對象,並把HttpContext.User設置為這個對象。後面MVC中間件在路由到相應Controller和Action的時候就可以根據Authorize特性中指定的認證和角色在HttpContext.User中進行檢查,不滿足檢查則跳轉至相應頁面。因此需要註意的就是一定要把Cookie中間件放在MVC中間件之前。

這裡需要特別說一下ClaimsPrincipal。一個ClaimsPrincipal對象中包含了一個或多個ClaimsIdentity對象,一個ClaimsIdentity對象一般來說對應著一個Cookie中某條鍵值對(個人理解)。Cookie中間件和ClaimsIdentity是通過AuthenticationScheme聯繫起來的。後面我們在寫自己的認證服務時,也是把Cookie中間件的AuthenticationScheme和創建的ClaimsIdentity一致。所以更準確地說是ClaimsIdentity包含了用戶認證和許可權的聲明,而ClaimsPrincipal可以包含多個ClaimsIdentity。當管道中存在多個Cookie中間件時,通過AuthenticationScheme進行區分。

在ClaimsIdentity中除了AuthenticationScheme外還有兩個比較重要的屬性,UserType和RoleType,其中UserType指定了用戶驗證類型,RoleType指定可角色驗證類型。意思就是如果我指定了RoleType為”RoleName”,那麼在進行角色認證時就會尋找Claims中所有的Type為”RoleName”的值,並檢查其中是否包含了Authorize中指定的RoleName。不過.NET Core中自帶了ClaimTypes,可以直接使用。例如角色類型就是ClaimTypes.Role。如果添加角色時用的自帶的ClaimTypes.Role,那麼在創建ClaimsIdentity時就不需要顯示指定RoleType了,預設角色認證就是使用ClaimTypes.Role。

關於Cookie中間件的添加,是通過Startup中Configure方法中的app.UseIdentity擴展方法實現的。這個擴展方法實際上添加了多種Cookie識別方式。在後面我在寫自己的用戶認證管理時只用一種。

 

0x04 自己寫用戶認證管理

瞭解了用戶認證的過程,我們可以自己寫認證管理來代替Identity組件了,同樣分為資料庫操作和認證業務邏輯。資料庫相關就不多說了,都寫到了IdentityRepository類,只有很簡單的數據操作。為了方便使用了Dapper,資料庫用的Sqlite。程式在啟動時會檢查資料庫表,沒有會自動創建空表。

認證服務也比較簡單就都寫到了IdentityService類,提供了註冊和登錄操作,註銷太簡了直接寫在了Action里。為了方便沒有提供角色管理頁面,如果要測試角色認證功能,需要手動去資料庫添加Role,然後在UserRoles中給用戶添加Role。

 

登錄:

註冊:

註銷:

具體示例可以到:

https://github.com/durow/NetCoreStudy

只是為了測試,邏輯上很多問題,比如用戶密碼明文存儲。重點看過程:)

0x05 寫在最後

第一次接觸Web應用,很多概念都不是很瞭解。就拿Cookie認證用戶來說,我之前的只知道通過Cookie識別用戶,一直以為是收到Cookie後再從資料庫或緩存中查出相應的許可權信息。不過看了自帶的Cookie中間件代碼後才知道認證信息是直接存在Cookie中的,這樣只要解密後反序列化就可以了。Identity這個程式集涉及了很多其它程式集(Security、HttpAbstraction等等),看得我很暈,最後總算搞明白了一些,很多細節也沒去深究,文中內容有的基於代碼,有的基於個人理解,有錯誤希望大家嘴下留情。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文想通過配置VS Code來實現對AngularJS的智能提示。在一般的情況下對於在HTML頁面是支持提示的。但是在js頁面就不是很友好,它是記憶你之前的輸入,要是之後有重覆的輸入,VS Code會提示您,僅此而已。 VS Code各種屌炸天的功能,將來必定是強大的前端IDE。 通過下列5步讓VS ...
  • 前些日子,Insus.NET有實現《ASP.NET MVC使用jQuery實現Autocomplete》http://www.cnblogs.com/insus/p/5638895.html 。 但今天嘗試把此功能移到ASP.NET Ajax UpdatePanel環境中使用。網頁在第一次載入時是沒 ...
  • Networkcomms 是一款C# 語言編寫的TCP/UDP通信框架 作者是英國人 以前是收費的 目前作者已經開源 開源地址是:https://github.com/MarcFletcher/NetworkComms.Net networkcomms通訊框架使用簡單方便,性能穩定. 從github ...
  • 傻了吧唧的裝雙系統.成功的乾崩了原本的系統.現在重裝VS.閑的沒事胡扯幾句. WindowsAPI在每一臺Windows系統上開放標準API供開發人員調用.功能齊全.在這裡只介紹三個部分. 1.利用API控制滑鼠鍵盤. 2.對外部程式的讀寫和監聽 3.對外部程式視窗的改動. 外部程式的意思就是.假設 ...
  • Hibernate提供了兩種映射一對一映射關聯關係的方式: 01.按照外鍵映射 02.按照主鍵映射 下麵以員工賬號表和員工檔案表(員工賬號和檔案表之間是一對一的關係)為例,介紹這兩種映射關係,並使用這兩種 映射方式分別完成以下持久化操作 (1)保存員工檔案的同時分配給員工一個賬號 (2)載入員工檔案 ...
  • 這段代碼很有意義,用於把一個程式的界面嵌入到我們自己程式的某個指定窗體上. 比如在某個項目里,我需要把基恩士的激光掃描輪廓顯示給客戶看,但是激光的DLL中並沒有這種功能提供. 於是我想先啟動激光的官方程式用以顯示輪廓, 然後再把這種顯示界面嵌入到我自己程式的界面上指定的位置上. 在筆者構想的PLC仿 ...
  • jquery easyui使用(三)······datagrid載入數據(未解決) ...
  • 工具幫幫我,tool885.com,成功登錄“Windows 應用商店”。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...