博客 / 詳情

返回

Access中實現基於Windows集成認證的SSO單點登錄

Hi,大家好!
今天我們來講一下如何獲取Windows賬號,實現單點登錄。
在構建企業級 Access 應用程序(C/S 架構)時,開發者往往面臨一個兩難選擇:是自己設計一套“用户表+密碼字段”的登錄系統,還是直接利用現有的企業基礎設施?
答案顯而易見。在域環境(Active Directory)下,利用 SSO(單點登錄) 是標準且最佳的實踐。

01什麼是SSO

SSO (Single Sign-On),即單點登錄。它的核心定義是:在多個應用系統中,用户只需要登錄一次,就可以訪問所有相互信任的應用系統。
在我們的 Access 開發場景中,指 Windows 集成認證 (Integrated Windows Authentication, IWA)。
舉個栗子簡單的理解一下:

  • 傳統模式:你去公司大樓(Windows),保安查了一次證件。進辦公室(Access系統)時,前台又要你背一遍身份證號和密碼。
  • SSO 模式:你刷卡進了公司大樓(Windows 登錄成功),你的工牌(Token)就是你的通行證。當你走進辦公室(打開 Access)時,系統只看你的工牌,確認是“自己人”,直接放行。

    02為什麼要用SSO

    很多開發者覺得:“我自己寫個密碼判斷 If txtPassword = "123456" 很簡單啊,為什麼要搞這麼複雜?”這是一個典型的誤區。
    引入 SSO 不僅僅是為了“少輸一次密碼”,是為了解決企業開發中的幾個問題:

  • 安全性Access 並不是一個專業的安全工具。存儲風險:如果你在 Access 表中存儲密碼(即使是 MD5 加密),一旦 .accdb 文件被拷貝,有無數種工具可以暴力破解。
  • 運維成本:終結“忘記密碼”的工單IT 部門的就不會再有軟件系統“重置密碼“的工單。只要用户能登錄 Windows,他就能登錄 Access。你不需要維護一套獨立的密碼庫,也不需要處理密碼找回請求。
  • 權限生命週期管理當員工離職時,IT 部門會禁用其 Windows 域賬號。如果 Access 有獨立的賬户體系,管理員忘記在 Access 裏禁用該員工,SSO 的優勢:域賬號一封禁,所有依賴 SSO 的系統(包括你的 Access)瞬間全部拒絕訪問。

    03核心代碼

    新建標準模塊 mod_Auth,代碼如下:

Option Compare Database
Option Explicit
' ---------------------------------------------------------
' API 聲明:兼容 VBA7 (x64) 及舊版本 (x86)
' ---------------------------------------------------------
#If VBA7 Then
    Private Declare PtrSafe Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" _
        (ByVal lpBuffer As String, nSize As Long) As Long
#Else
    Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" _
        (ByVal lpBuffer As String, nSize As Long) As Long
#End If
' ---------------------------------------------------------
' 函數:GetSystemUser
' 描述:通過 API 獲取當前 Windows 登錄賬户名
' 原理:讀取當前線程的安全令牌,而非環境變量
' ---------------------------------------------------------
Public Function GetSystemUser() As String
    Dim strBuffer As String
    Dim lngSize As Long
    Dim lngResult As Long
    
    ' 初始化緩衝區:API 需要預先分配內存空間
    ' 255 字符通常足以容納 Windows 用户名
    strBuffer = String(255, vbNullChar)
    lngSize = Len(strBuffer)
    
    ' 調用 API
    ' lpBuffer: 接收用户名的緩衝區
    ' nSize: 傳入緩衝區長度,返回實際用户名長度
    lngResult = GetUserName(strBuffer, lngSize)
    
    If lngResult <> 0 Then
        ' API 返回成功 (非0)
        ' 注意:lngSize 返回的是包含 Null 結尾的長度,需要 -1
        GetSystemUser = Left$(strBuffer, lngSize - 1)
    Else
        ' API 調用失敗 (通常極少發生,除非系統底層異常)
        GetSystemUser = "Unknown"
        ' 實際生產中建議在此處記錄 Err.LastDllError
    End If
End Function

04架構設計

獲取用户名只是第一步,完整的權限控制需要數據庫層面的配合。建議採用 RBAC (基於角色的訪問控制) 模型。這裏我們簡單的來描述一下。

  1. 數據庫 Schema 設計在後端數據庫(或本地表)創建 sys_Users 表:User_ID (PK, AutoNumber)Win_Account (String, Indexed, Unique) - 存儲 Windows 登錄名Role_Code (String) - 例如: 'ADMIN', 'VIEWER'Is_Active (Boolean) - 軟刪除標記
  2. 啓動掛載邏輯利用 Access 的啓動窗體(Splash Screen)作為控制器。在啓動窗體 frm_Splash 的 Form_Load 事件中:

    Private Sub Form_Load()
        On Error GoTo ErrorHandler
        
        Dim strCurrentUser As String
        Dim strRole As String
        
        ' 1. 獲取系統標識 (SSO 核心步驟)
        strCurrentUser = GetSystemUser()
        
        ' 2. 數據庫鑑權 (Authorization)
        ' 認證(Authentication)由 Windows 完成,Access 只負責授權(Authorization)
        strRole = Nz(DLookup("Role_Code", "sys_Users", _
            "Win_Account='" & strCurrentUser & "' AND Is_Active=True"), "")
            
        ' 3. 邏輯分發
        If Len(strRole) = 0 Then
            LogAccessAttempt strCurrentUser, "FAILED" ' 記錄審計日誌
            MsgBox "Access Denied: User [" & strCurrentUser & "] not authorized.", vbCritical
            Application.Quit acQuitSaveNone
        Else
            ' 初始化全局會話變量
            TempVars.Add "Current_User", strCurrentUser
            TempVars.Add "Current_Role", strRole
            
            LogAccessAttempt strCurrentUser, "SUCCESS"
            
            ' 根據角色跳轉
            DoCmd.OpenForm "frm_MainDashboard"
        End If
        
        Exit Sub
    ErrorHandler:
        MsgBox "System Error: " & Err.Description, vbCritical
        Application.Quit
    End Sub

    05總結

    通過引入 SSO,我們將 Access 的身份驗證委託給了最值得信任的操作系統。這不僅讓代碼更簡潔(無需編寫複雜的密碼哈希、加鹽邏輯),更讓整個系統的安全架構提升到了企業級標準。

**喜歡這篇文章嗎?歡迎點贊、在看、轉發,讓更多 Access 愛好者看到!

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.