ASP.NET沒有魔法——ASP.NET Identity 的“多重”身份驗證代碼篇

来源:http://www.cnblogs.com/selimsong/archive/2017/12/01/7942513.html
-Advertisement-
Play Games

上篇文章介紹了ASP.NET中身份驗證的機制與流程,本文將使用代碼的來介紹如何實現第三方賬戶驗證與雙因數驗證。 本章主要內容有: ● 實現基於微軟賬戶的第三方身份驗證 ● 實現雙因數身份驗證 ● 驗證碼機制 實現基於微軟賬戶的第三方身份驗證 在微軟提供的ASP.NET MVC模板代碼中,預設添加了微 ...


  上篇文章介紹了ASP.NET中身份驗證的機制與流程,本文將使用代碼的來介紹如何實現第三方賬戶驗證與雙因數驗證。

  本章主要內容有:
  ● 實現基於微軟賬戶的第三方身份驗證
  ● 實現雙因數身份驗證
  ● 驗證碼機制

實現基於微軟賬戶的第三方身份驗證

  在微軟提供的ASP.NET MVC模板代碼中,預設添加了微軟、Google、twitter以及Facebook的賬戶登錄代碼(雖然被註釋了),另外針對國內的一些社交賬戶提供了相應的組件,所有組件都可以通過Nuget包管理器安裝:

  

  從上圖中看到有優酷、微信、QQ、微博等組件,其中一些是微軟提供的,一些是其它開發者提供的。而本文將使用微軟賬戶為例來介紹如何實現一個第三方登錄。
  註:本章主要代碼參考ASP.NET MVC模板代碼,所以在文章中只列出關鍵代碼,其餘代碼與模板中的完全一致。

組件安裝及Key申請

  在開發之前首先需要通過Nuget安裝Microsoft.Owin.Security.MicrosoftAccount:

  

  另外就是需要去微軟的開發者中心使用微軟賬戶創建一個自己的應用信息https://apps.dev.microsoft.com/,並保存應用的ID以及密鑰用於對身份驗證中間件進行配置:

  

  創建過程如下:
  1. 點擊添加應用按鈕,進入應用程式註冊頁面,填寫應用名稱並點擊Create按鈕(註:由於我已經有一個名稱為My Blog的App,所以下麵的Test App的創建流程僅僅是用於演示,後續的身份驗證實際上是使用之前創建的My Blog):

  

  2. 在後續頁面中點擊生成新密碼來生成密鑰(註:該密碼只顯示一次,需要在彈出框中複製並保存下來):

  

  3. 添加平臺:點擊添加平臺按鈕,添加一個Web平臺,併在平臺的重定向Url中填入本地調試的地址信息(註:一定需要啟動HTTPS並且地址後需要添加signin-microsoft,VS可以在項目的屬性中開啟SSL,並設置SSL的URL):

  

  

 

   4. 保存更改。

添加中間件

  在上一篇文章中介紹了,第三方賬戶身份驗證除了特定賬戶身份驗證中間件外,還需要添加一個消極模式的外部Cookie身份驗證中間件,所以首先需要在項目的Startup文件中添加一下代碼:

  

  然後再在該中間件後加入微軟身份驗證中間件(註:中間件順序會影響處理流程,微軟身份驗證中間件必須在外部Cookie中間件後),並設置上面創建的應用ID及密鑰:

  

添加Controller及頁面的功能支持

  現在可以說應用中已經支持微軟的賬戶身份驗證了,但是在應用中還未提供微軟身份驗證的入口,以及登陸後用戶信息的補全等功能。
  1. 在頁面上添加驗證入口,在Login頁面上加入以下代碼,通過AuthenticationManager來獲取所有的第三方身份驗證方式,並生成對應鏈接:

  

  

 2. 在AccountController中添加ExternalLogin Action方法(註:該方法主要目的是調用AuthenticationManager的Challenge方法來觸發微軟身份驗證中間件的ResponseChallenge方法來完成頁面的跳轉):

   

  其中ChallengeResult是一個自定義的ASP.NET MVC Reuslt類型:

  

  3. 加入第三方驗證後的回調方法ExternalLoginCallback,該回調方法是獲取第三方身份驗證後的用戶信息,然後在本地資料庫中查找該用戶,如果存在那麼登錄成功,否則需要對該用戶信息進行補全。

  

  4. 添加第三方賬戶信息補全頁面及Action方法,其中action方法接收到補全的用戶信息後完成用戶註冊功能,但要註意的是第三方賬戶沒有密碼,僅僅是在AspNetUserLogins表中添加了第三方驗證的信息:

   

  運行結果:
  1.訪問登錄頁面出現Microsoft的按鈕(註:必須使用HTTPS地址才能正常的使用微軟身份驗證):

  

  2. 點擊微軟身份驗證按鈕後,跳轉到微軟賬戶登錄頁面:

  

  

  3. 完成登錄後,由於是第一次登錄,所以會跳轉到信息補全頁面:

  

  輸入郵箱後將登錄成功:

  

  資料庫中的信息:

  

  上圖中可以看到無密碼,然後在Login表中有一條數據:

  

實現雙因數身份驗證

  Identity的雙因數身份驗證實際上是Identity的一個內置功能,為什麼說是內置呢?因為只需要實現信息的發送(如郵件、簡訊等),然後再對Identity中的SignInManager進行簡單的配置然後添加一些用於發送、填寫驗證碼的頁面就可以完成。所以首先需要完成的就是實現信息發送功能。
  註:這裡信息發送功能使用將信息寫到硬碟的方式模擬。
  1. 實現信息的發送:
  在ASP.NET MVC預設的模板中就為我們創建瞭如下代碼:

   

  預設的郵件及簡訊發送器,只不過它沒有實現,僅僅是返回了一個空值,現在使用寫硬碟的方式將信息寫到硬碟上:

   

  2. 完成UserManager的雙因數驗證配置:

  

  三個關鍵點:1. TokenProvider,它用來生成驗證碼。2. 信息格式。3. 信息發送服務。

  3. 在身份驗證管道中加入雙因數驗證中間件:

  

  兩個中間件前者用於處理二次驗證,後者用於記住登錄狀態,下次訪問系統時自動登錄。

  4. 添加驗證碼發送方式選擇以及驗證碼填寫頁面及相應的Action方法(代碼略)。
  5. 在資料庫中將演示用的用戶信息改為啟用二次驗證(註:模板代碼中有用於管理個人信息的功能,此處省略了實現,直接通過修改數據數據的方式開啟用戶的雙因數驗證、添加電話號碼等):

  

  6. 運行結果:
  登錄後需要選擇驗證碼發送方式:

  

  選擇後點擊提交按鈕,頁面調整到驗證頁面的同時,指定的文件中生成了需要的驗證碼:

  

  

  填寫驗證碼後點擊提交按鈕,則登錄成功:

  

  

  註:雙因數驗證也可以應用到第三方賬戶的登錄方式上,雙因數驗證只與用戶有關與身份驗證方式無關。

驗證碼機制

  對於雙因數驗證來說,它實際上就是在普通驗證或第三方賬戶驗證的基礎上增加了驗證碼的發送和驗證兩個環節,那麼對於驗證碼這個主體Identity是如何來維護的呢?
  在上面的介紹中,有一個環節就是需要通過對UserManager進行配置以支持雙因數驗證的消息發送、消息生成等等:

  

  根據這個代碼看來XXXTokenProvider是專門用來維護驗證碼的,而XXXService是用來發送的,所以這裡將對TokenProvider進行說明,瞭解驗證碼是如何維護的:

  

  上圖是TokenProvider相關的一個簡單類圖,從類圖中可以看出TokenProvider實際上是實現了一個名為IUserTokenProvider的介面,該介面中有4個方法,它們的作用分別是:
  ● GenerateAsync:根據UserManager以及User信息來生成一個令牌(Token)。
  ● IsValidProviderForUserAsync:判斷這個Token提供器對這個用戶是否是有效的(如果使用簡訊驗證,但是該用戶沒有設置手機號,那麼就是無效的)。
  ● NotifyAsync:當Token生成後調用該方法通知用戶,如簡訊或郵件通知。
  ● ValidateAsync:用於驗證Token是否有效。

  而TotpSecutityStampBasedTokenProvider是一個實現了IUserTokenProvider介面的,通過用戶安全戳生成驗證碼的生成器:

  

  從代碼中可以看到該演算法是基於rfc6238(TOTP: Time-Based One-Time Password Algorithm,基於時間的一次性密碼演算法) https://tools.ietf.org/html/rfc6238,然後通過用戶的安全戳以及GetUserModifierAsync方法生成特定的信息熵來完成密碼加密,關於信息熵可參考:https://www.zhihu.com/question/22178202,上面將生成後的令牌執行ToString("D6")是將其轉換為一個6位數字的字元串。
  而Token的驗證方式和生成差不多都是通過用戶安全戳和信息熵來驗證提交的驗證碼(它實際上是一種hash演算法):

  

  以上已經解釋了最初驗證碼的生成和驗證的問題,所以對於EmailTokenProvider和PhoneNumberTokenProvider只是對熵的生成、對Provider的有效性(是否存在Email或電話號碼)、通知方式進行了修改,下麵是PhoneNumberTokenProvider相關代碼:

  

  

  

小結  

  本章主要是使用代碼的形式實現了ASP.NET中的第三方驗證和雙因數驗證,文中的代碼都來自ASP.NET MVC的模板,所以文中僅僅是對關鍵的代碼進行了介紹,一些細節的內容可參考完整代碼。其中第三方驗證使用的是微軟賬戶,如果有環境支持可以嘗試國內的微信、QQ等身份驗證。
  另外在文章最後對驗證碼的生成和校驗代碼進行了分析,知道了它是基於Hash演算法的信息加密、驗證的機制來實現的。
ASP.NET MVC基於Identity提供了非常完善、強大的用戶管理和身份驗證功能,除了以上介紹的以外還有賬戶鎖定、註冊郵箱或簡訊驗證功能,基本上已經涵蓋了現在開發常用的功能,但這些功能被一個模板實現了,所以ASP.NET強大嗎?

參考:

  https://www.zhihu.com/question/22178202
  https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/external-authentication-services
  https://www.benday.com/2014/02/25/walkthrough-asp-net-mvc-identity-with-microsoft-account-authentication/

本文鏈接:http://www.cnblogs.com/selimsong/p/7942513.html 

ASP.NET沒有魔法——目錄


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

-Advertisement-
Play Games
更多相關文章
  • 鏈接的地址,可以根據路由規則動態生成,不用寫死,文檔結構有變化時,依然可以找到正確的路徑 1.url.Action(只生成URL) 有很多重載方法,可以根據需要選擇,生成URL時,會根據路由規則生成,不過調用時也是根據路由規則定址,所以OK 2.Html.ActionLink(生成整個Link標簽) ...
  • 你有一個函數,其中完全取決於參數值而採取不同行為。針對該參數的每個可能值,建立一個獨立的函數。 ...
  • Nginx集群可以實現基於Http Basic身份驗證,通過輸入用戶、密碼,經過SSL協議的HTTPS,從而實現有效的身份驗證並訪問相應的WebApi。當然,訪問的方式不僅僅基於Http Basic一種,還可以通過令牌token的方式進行訪問,又或者基於redis實現單點登錄的訪問,本文主要講述的是... ...
  • 先看下麵的這組字元,如果輸出來,它是無法靠右對齊: string[] s1 = { "300", "5", "54210", "6300", "88" }; foreach (string s in s1) { string s2 = s; Console.WriteLine(s2); } C#的處 ...
  • 本人多年來一直在獨自設計並開發一種“面向表達”的編程語言——S#,以求達到數據即程式、程式即數據的最高境界,可以包容大多數慣用的語言特性。直至今天初步成形,特此在博客園上開篇介紹,通過分享和交流進一步發揚光大。 ...
  • 一 抽象類 描述一個事物,由於沒有足夠的信息,這時就將這個事物稱為抽象事物。abstract為抽象關鍵字,被其聲明的類稱為抽象類,其聲明的方法稱為抽象方法。 抽象屬性聲明不提供屬性訪問器的實現,它只聲明該類支持的屬性,而訪問器的實現留給派生類。 抽象方法聲明不提供方法的實現,他必須是一個空方法,而將 ...
  • 最近需要向客戶發送一些宣傳資料,Excel列表裡面有一兩百個記錄,本來想手寫就算了,估摸著也花不了多少時間,不過寫完一個信封我就後悔了,整天敲著鍵盤,書寫的字太難看了,而且感覺手還是有點累。才第一個啊,想著後面還有那麼多,感覺整個人頭都大了,只好放棄,太沒技術含量了。然後尋找有無一些套打的的軟體,不... ...
  • jquery.qqFace.js使用方法 引用 <script src="~/Content/qqFace/js/jquery.qqFace.js?v=3"></script> <script src="~/Content/qqFace/js/jquery-browser.js"></script> ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...