首页 / 军事 / 环球军事 / 正文

user is not authorized(Access中实现基于Windows集成认证的SSO单点登录)

放大字体  缩小字体 来源:北京最牛钉子户 2026-04-17 17:25  浏览次数:10

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 不仅仅是为了“少输一次密码”,是为了解决企业开发中的几个问题:

1. 安全性

Access 并不是一个专业的安全工具。

存储风险:如果你在 Access 表中存储密码(即使是 MD5 加密),一旦 .accdb 文件被拷贝,有无数种工具可以暴力破解。

2. 运维成本:终结“忘记密码”的工单

IT 部门的就不会再有软件系统“重置密码“的工单。只要用户能登录 Windows,他就能登录 Access。你不需要维护一套独立的密码库,也不需要处理密码找回请求。

3. 权限生命周期管理

当员工离职时,IT 部门会禁用其 Windows 域账号。如果 Access 有独立的账户体系,管理员忘记在 Access 里禁用该员工,SSO 的优势:域账号一封禁,所有依赖 SSO 的系统(包括你的 Access)瞬间全部拒绝访问。

03

核心代码

新建标准模块 mod_Auth,代码如下:

Option Compare DatabaseOption 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 IfEnd 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 SubErrorHandler:    MsgBox "System Error: " & Err.Description, vbCritical    Application.QuitEnd Sub

05

总结


通过引入 SSO,我们将 Access 的身份验证委托给了最值得信任的操作系统。这不仅让代码更简洁(无需编写复杂的密码哈希、加盐逻辑),更让整个系统的安全架构提升到了企业级标准。


喜欢这篇文章吗?欢迎点赞、在看、转发,让更多 Access 爱好者看到!

打赏
0相关评论
热门搜索排行
精彩图片
友情链接
声明:本站信息均由用户注册后自行发布,本站不承担任何法律责任。如有侵权请告知立立即做删除处理。
违法不良信息举报邮箱:115904045
头条快讯网 版权所有
中国互联网举报中心