Credential Provider Framework 簡單紀錄


先講一下,這篇算是 Heresy 自己針對微軟的「Credential Provider Framework」的一些研究筆記;基本上,Heresy 還沒有完全搞清楚,很多細節都還不知道到底該怎麼用,而且 Heresy 自己的目標也還沒達到…

老實說,由於這並不是 Heresy 主要該做的事,所以也在考慮要不要繼續研究,還是乾脆放棄算了?不過,在這邊還是先記錄一下目前研究的結果吧。而由於 Heresy 自己也還在摸索中,所以本文的內容不保證正確!如果有錯誤,也歡迎指證。

首先,「Credential Provider Framework」(MSDN)是 Windows Vista 之後,用來做 Windows 登入、解鎖的架構。在 Windows 鎖定畫面時,如果有其他的登入方法(例如指紋辨識),應該都是透過這個方法來實作的。

目前他應該是有兩個版本,Windows Vista 和 Windows 7 用的是 v1,Windows 8.x 和 Windows 10 則是 v2,兩個版本的介面(interface)略有不同,不過 Windows 8.x 和 Windows 10 還是可以使用 v1 的實作。

而實際上,Windows 在登入認證時的流程,大致上會如下圖(出自《Credentials Processes in Windows Authentication》)所示:

基本上,使用者看到的登入畫面,是「Logon UI」的部分,而內部實際上進行 Windows 的登入管理的則是「Winlogon」;在兩者之間,實際上並沒有直接聯繫,而是透過「Credential UI」來做溝通。

在登入時,「Credential UI」會透過「Credential Provider」提供的資料,來顯示登入畫面,並將使用者輸入的內容、傳遞回「Credential Provider」、然後產生出「Credential 」給 Winlogon 進行認證。


這次 Heresy 想做的事情,實際上就是自己去寫的一個「Credential Provider」,來進行遠端登入解鎖的功能。

不過 Heresy 沒有找到比較完整、詳細的教學,所以只好從範例程式來研究了。主要的參考資料如下:

  • v1 的範例包「Windows Vista Credential Provider Samples」連結
    裡面有五個不同情境的範例,另外也有一份 Overview 的文件,所以建議抓下來看看。

  • v2 的範例是「V2 Credential Provider Sample」連結
    它的內容比較簡單,只有一個,也沒有文件可以參考;所以個人是搭配 v1 的文件,以及《Credential Provider Framework Changes in Windows 8》這份文件(連結)來研究的。

這些範例專案建置完成之後,都是單一的 DLL 檔,只要把檔案丟到 C:\Windows\system32 目錄下、然後再去執行對應的「register.reg」,把資訊加到 Windows 的登錄檔裡就可以完成安裝了;而且完成安裝後,不需要重新開機,只要鎖定電腦(Win + L)、進入 Windows 的登入畫面,就可以做測試了。

而如果測試完要拿掉,可以直接把 DLL 砍掉,並執行對應的「Unregister.reg」,就可以了。

以 v2 的 Credential Provider 來說,如果單一使用者有多個可用的 Credential Provider 的話,在登入畫畫面中,會出現「Sign-in Option」的選項,點下去之後會有小圖示、展開出可以使用的認證方法。例如下圖(圖片來源為《Credential Provider Framework Changes in Windows 8》)就是 Windows 8 的登入畫面,該使用者有兩種登入方法。

而如果是 v1 的話,他則是會在使用者列表的部分,多出額外的選項可以選擇;下圖中的「Fabrikam Sign-in」就是 v1 的 Credential Provider。

所以這邊也看得出來,基本上 v2 的概念,是「使用者優先」(Windows 8、Windows 10);而 v1 的概念,則是「登入方法」優先,兩者是不太一樣的。


Heresy 目前主要是以「SampleV2CredentialProvider」這個範例來做研究;而其中,主要需要研究的應該是「CSampleCredential」和「CSampleProvider」這兩組檔案;在這兩組檔案(.h + .cpp)中,都各自有同名的類別,分別繼承自系統的類別。

CSampleProvider 基本上是對外溝通的部分,他的型別繼承自 ICredentialProviderMSDN)和 ICredentialProviderSetUserArrayMSDN)。

CSampleCredential 則是提供對應單一使用者的登入憑證,讓 ICredentialProvider 可以回報給登入系統、並完成登入;同時,他也會告訴 Logoon UI 自己的客製化界面的定義。他的型別繼承自 ICredentialProviderCredential2MSDN)和 ICredentialProviderCredentialWithFieldOptionsMSDN)。

在進入登入畫面的時候,CSampleProvider 的物件會被建立出來,然後下列的函式、會被依序呼叫到(不是全部都有列出來):

  • SetUsageScenario():LogonUI 告訴 Provider 目前的使用情境
  • SetUserArray():LogonUI 提供 Provider 系統的使用者列表
  • Advise():LogonUI 提供 Provider 一個 callback、以供操作
  • GetCredentialCount():Provider 告訴 LogonUI 自己可以提供的憑證數量、以及登入類型
  • GetCredentialAt():Provider 告訴 LogonUI 特定的使用者的登入憑證

而這邊要注意的是,SampleV2CredentialProvider 這個範例程式裡的 CSampleProvider 並沒有針對系統上每一個使用者都產生對應的 CSampleCredential,而是只針對第一個使用者產生、並於 GetCredentialCount() 回報 1、代表只有第一個使用者可以透過 SampleV2CredentialProvider 來登入;所以如果希望系統上的每個使用者都可以 SampleV2CredentialProvider 來做登入認證的話,這部分是需要修改的。

CSampleCredential 的部分,實際上被建立出來,是在 CSampleProvider::_EnumerateCredentials() 這個函式中,他會在 CSampleProviderGetCredentialCount() 被呼叫到時執行。

而之後,當 GetCredentialAt() 被呼叫到之後,則是會依序被執行下列的函式:

  • GetUserSid(): 回報自己對應的使用者的 SID
  • Advise():LogonUI 提供 Provider 一個 callback、以供操作
  • SetSelected():將此使用者設定為被選取的狀態,另外也有對應的 SetDeselected(),不過這邊沒被呼叫到

當使用者輸入完密碼、按下確認後,則會執行到:

  • GetSerialization():根據使用者的輸入,產生一個登入用的、序列化過的憑據(serialized credential)、讓系統用來判斷是否可以正確登入。
  • ReportResult():回報登入結果的文字訊息、以及狀態圖示。

而為了要讓使用者可以輸入、調整登入的參數,SampleV2CredentialProvider 也有描述各項欄位的資訊,不過在這邊由於不是 Heresy 的重點,所以就先跳過了;如果想要修改的話,相關的設定主要是定義在「common.h」這個檔案內,而在上述兩個類別之中,也都有對應的函式。

所以,要實作登入的機制,看來最重要的,應該就是 GetSerialization() 了。他最主要要做的,就是填好一份「CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION」(MSDN)、讓系統可以用來做登入的驗證。

而此時,除了要把用來做登入驗證的資訊序列化外,也還需要指定要使用哪一個「Authentication Package」來做登入認證的檢查(參考);不過到了這邊,就是 Heresy 還沒研究的部分了…認真講,要搞到這部分的話,對 Heresy 來說看來就太過深入了…


其他的部分:

  • 不知道為啥,在 Hyper-V 的 VM 裡面試不出來,後來都是在實體機器上測試。

  • CSampleProvider::Advise() 被呼叫的時候,會得到一個 ICredentialProviderEvents 的 callback,之後透過呼叫他的 CredentialsChanged(),可以要求系統重新產生 Credential。

  • 理論上,把 CSampleProvider::GetCredentialCount()pbAutoLogonWithDefaultCSampleCredential::SetSelected()pbAutoLogon 都設定成 true,應該要可以跳過 UI 直接登入,不過 Heresy 這邊看來還是得按滑鼠…


這篇大致上就先寫到這裡了。會不會有下一篇?還不知道…(遠目

不過,最後要再提醒一下,Credential Provider 是下去改 Windows 登入的機制,基本上…算是有點風險的東西。Heresy 曾經搞到自己有個帳戶沒辦法登入,後來是透過另一個帳戶進去、把 Credential Provider 拿掉才解決的。所以在測試的時候,請小心謹慎!

對「Credential Provider Framework 簡單紀錄」的想法

  1. 你好,

    我現在是把官方的V2 Sample下載了下來,並且把pdwCount改成了100。 可是,還是不行誒。。。Sign-in option那邊沒有這個選項 Q_Q。你有什麼想法嗎?謝謝你

  2. 您好,

    我下載v1 的範例包「Windows Vista Credential Provider Samples」
    編譯SampleCredentialProvider後將dll檔放到WIN7上
    出現Administrator跟Guest這兩個新的user
    我有看一下程式碼可是找不到哪裡是設定密碼的地方
    想問一下您是否知道密碼
    或是如何登入的方法

    謝謝

    • 抱歉,不知道你的問題到底是要問什麼?
      他多出來的 Administrator 和 Guest 這兩個帳號都是系統本來就有的,並不是他自己的。
      理論上你還是要輸入本來的帳號密碼來登入。

  3. 結果,之前 Credential Provider 研究了老半天,還是不能自動登入。結果今天心血來潮,把程式從 v2 改成 v1 就可以了。 orz
    不過,在 Windows 7 目前無法使用。

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.