本篇內容主要講述了實現基于微軟賬戶的第三方身份驗證、實現雙因子身份驗證、 驗證碼機制這3個內容。
實現基于微軟賬戶的第三方身份驗證
在微軟提供的asp.net mvc模板代碼中,默認添加了微軟、google、twitter以及facebook的賬戶登錄代碼(雖然被注釋了),另外針對國內的一些社交賬戶提供了相應的組件,所有組件都可以通過nuget包管理器安裝:
從上圖中看到有優酷、微信、qq、微博等組件,其中一些是微軟提供的,一些是其它開發者提供的。而本文將使用微軟賬戶為例來介紹如何實現一個第三方登錄。
注:本章主要代碼參考asp.net mvc模板代碼,所以在文章中只列出關鍵代碼,其余代碼與模板中的完全一致。
組件安裝及key申請
在開發之前首先需要通過nuget安裝microsoft.owin.security.microsoftaccount:
另外就是需要去微軟的開發者中心使用微軟賬戶創建一個自己的應用信息,并保存應用的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強大嗎?
原文鏈接:http://www.cnblogs.com/selimsong/p/7942513.html