ASP.NET MVC Windows授权项目对接AD实现个人账号及额外数据存储咨询
功能实现方案
核心结论
你需要将额外用户信息、多照片数据存储在MS SQL中,该方案对现有AD对接逻辑侵入性最低,灵活性和可维护性远高于扩展AD schema,可直接适配现有体系。
具体实现步骤
步骤1:确定关联主键
直接使用现有
Person模型中的EmployeeNumber(AD域内全局唯一的员工编号)作为AD用户与SQL扩展数据的唯一关联键,不要用DisplayName作为匹配依据,避免重名导致的数据关联错误,同时你现有Details接口的查询参数建议同步从name改为employeeNumber修复隐患。步骤2:设计SQL表结构
只需新增2张表即可满足需求:
- 用户扩展信息表
UserExtensions,存储AD不存在的自定义用户属性:
字段名 类型 说明 EmployeeNumber int 主键,关联AD用户的员工编号 你需要的自定义字段(比如个性签名、紧急联系人等) 对应类型 按需添加 - 用户照片表
UserPhotos,存储多照片关联信息(建议照片文件存在本地文件服务器/站点指定目录,数据库只存关联属性,避免数据库体积过大):
字段名 类型 说明 Id int 主键 EmployeeNumber int 外键,关联 UserExtensions.EmployeeNumberPhotoPath nvarchar(200) 照片文件存储路径 UploadTime datetime 上传时间 PhotoType tinyint 照片类型(比如证件照、生活照等,可自定义) - 用户扩展信息表
步骤3:扩展现有模型
给
Person类新增扩展属性:public class Person { // 原有属性保持不变 public string DisplayName { get; set; } public string Office { get; set; } public string PhoneNumber { get; set; } public string ExtensionPhoneNumber { get; set; } public string Email { get; set; } public string Department { get; set; } public string Title { get; set; } public int DepartmentNumber { get; set; } public string Subdivision { get; set; } public string Manager { get; set; } public string Mobile { get; set; } public int EmployeeNumber { get; set; } public string company { get; set; } public DateTime BirthDay { get; set; } // 新增扩展属性 // 自定义扩展信息 public string CustomSignature { get; set; } public string EmergencyContact { get; set; } // 多照片列表 public List<UserPhoto> Photos { get; set; } = new List<UserPhoto>(); } // 新增照片模型 public class UserPhoto { public int Id { get; set; } public string PhotoPath { get; set; } public DateTime UploadTime { get; set; } public byte PhotoType { get; set; } }步骤4:适配现有查询逻辑
原有AD查询逻辑完全不用修改,只需要在拉取到AD的
Person数据后,拼接SQL中的扩展数据即可,示例逻辑如下:public static List<Person> GetPeople() { List<Person> people = new List<Person>(); // 原有AD查询逻辑保持不变 var path = new PrincipalContext(ContextType.Domain, "Domain", "OU=Domain, DC=Domain, DC=Domain"); UserPrincipal user = new UserPrincipal(path); user.Enabled = true; user.Name = "*"; user.EmailAddress = "*"; var search = new System.DirectoryServices.AccountManagement.PrincipalSearcher(); search.QueryFilter = user; var results = search.FindAll(); // 提前从SQL中一次性查出所有用户的扩展信息和照片,避免循环查库 var allExtensions = DbContext.UserExtensions.ToList(); var allPhotos = DbContext.UserPhotos.ToList(); foreach (UserPrincipal item in results) { var directoryEntry = item.GetUnderlyingObject() as DirectoryEntry; var person = new Person { // 原有属性赋值逻辑保持不变 DisplayName = item.Name, PhoneNumber = item.VoiceTelephoneNumber, ExtensionPhoneNumber = item.VoiceTelephoneNumber, Email = item.EmailAddress, Office = directoryEntry.Properties["physicalDeliveryOfficeName"].Value as string, Department = directoryEntry.Properties["subdivision"].Value as string, Title = directoryEntry.Properties["title"].Value as string, DepartmentNumber = Convert.ToInt32(directoryEntry.Properties["departmentNumber"].Value), Subdivision = directoryEntry.Properties["department"].Value as string, Manager = directoryEntry.Properties["manager"].Value as string, Mobile = directoryEntry.Properties["mobile"].Value as string, EmployeeNumber = Convert.ToInt32(directoryEntry.Properties["employeeNumber"].Value), company = directoryEntry.Properties["company"].Value as string, BirthDay = Convert.ToDateTime(directoryEntry.Properties["postOfficeBox"].Value) }; // 拼接SQL中的扩展数据 var extension = allExtensions.FirstOrDefault(e => e.EmployeeNumber == person.EmployeeNumber); if(extension != null) { person.CustomSignature = extension.CustomSignature; person.EmergencyContact = extension.EmergencyContact; } person.Photos = allPhotos.Where(p => p.EmployeeNumber == person.EmployeeNumber).ToList(); people.Add(person); } return people; }步骤5:适配现有权限体系
你已实现基于AD安全组的授权机制,新增的个人信息修改、照片上传接口直接复用现有权限校验逻辑即可:
- 普通用户仅可查询、修改自身对应
EmployeeNumber的扩展信息和照片 - 管理员安全组内的用户可操作所有用户的扩展数据
无需额外开发新的身份认证逻辑。
- 普通用户仅可查询、修改自身对应
方案优势
- 完全不修改现有AD配置、AD查询逻辑,对现有功能无侵入
- 后续要新增自定义属性只需修改SQL表和模型,灵活度极高
- 不会增大AD数据库体积,不影响域控服务稳定性
内容的提问来源于stack exchange,提问作者Азат Гафаров
相关产品推荐
相关产品推荐

