1. 引言
最近一段时间设计和实现公司内部的基于 OAuth2.0 的统一身份认证中心, 经梳理, 公司部分自研系统可以使用 OAuth2.0 的方式进行身份认证, 还有一部分系统无源代码, 未开放接口, 使用 windows 用户作为系统的用户. 面对这种情况, 同时为实现一个中心一键开关账户的功能, 对于无源码, 未开放接口, 使用 windows 用户作为系统用户的系统, 单独开发接口程序, 有数据库的直接操作数据库将账号密码同步至数据库中; 对于使用 windows 用户作为系统用户的系统, 则在其部署的服务器上部署 webapi 接口, 同步管理用户和密码. 本文主要介绍的是 C# 对 windows 本地用户的新增, 删除, 修改密码功能以及列出所有本地用户的功能.
2. Active Directory 与 DirectoryEntry 类
- C# 管理 windows 用户, 在百度上搜索到 c# 操作 windows 本地账户 https://www.cnblogs.com/chengeng/p/4173726.html 这样一篇文章, 主要是通过导入 Netapi32.dll 文件实现对 windows 本地账户的管理. 而在之前有做过使用 DirectoryEntry 类修改本地用户密码的功能, 经搜索, DirectoryEntry 类可封装 Active Directory 域服务层次结构中的节点或对象, 也能实现对用户的新增, 删除以及其他功能.
- Active Directory
活动目录 (Active Directory) 是面向 Windows Standard Server,Windows Enterprise Server 以及 Windows Datacenter Server 的目录服务.(Active Directory 不能运行在 Windows Web Server 上, 但是可以通过它对运行 Windows Web Server 的计算机进行管理.)Active Directory 存储了有关网络对象的信息, 并且让管理员和用户能够轻松地查找和使用这些信息. Active Directory 使用了一种结构化的数据存储方式, 并以此作为基础对目录信息进行合乎逻辑的分层组织.
可参考: Active Directory 的基本概念 https://www.cnblogs.com/IFire47/p/6672176.html
DirectoryEntry 类
DirectoryEntry 类位于 System.DirectoryServices 表空间下, 可封装 Active Directory 域服务层次结构中的节点或对象. DirectoryEntry 类使用 Active Directory Services Interfaces (ADSI) 技术. ADSI 是 Microsoft 为灵活的工具提供用于处理各种网络提供程序的接口的集合. ADSI 使管理员能够定位和管理网络上的资源相对容易地, 而不考虑网络的大小.
可参考: DirectoryEntry 类 https://msdn.microsoft.com/zh-cn/library/system.directoryservices.directoryentry.aspx
3. 管理本地用户
- using System;
- using System.Collections.Generic;
- using System.DirectoryServices;
- using System.Linq;
- using System.Web;
- namespace OAuthClient.Common
- {
- public class WindowsUser : IUser
- {
- private static readonly string PATH = "WinNT://" + Environment.MachineName;
- /// <summary>
- /// 获取所有用户
- /// </summary>
- /// <returns></returns>
- public List<User> GetAllUser()
- {
- List<User> list = new List<User>();
- using (DirectoryEntry deRoot = new DirectoryEntry(PATH))
- {
- if (deRoot.Children != null)
- {
- foreach (DirectoryEntry de in deRoot.Children)
- {
- if (de.SchemaClassName == "User" ||
- de.SchemaClassName == "Computer" ||
- de.SchemaClassName == "Domain")
- {
- User user = new User()
- {
- name = de.Name,
- fullname = de.Properties["FullName"].Value.ToString()
- };
- list.Add(user);
- }
- }
- }
- return list;
- }
- }
- /// <summary>
- /// 新增用户
- /// </summary>
- /// <param name="user"></param>
- /// <returns></returns>
- public string AddUser(User user)
- {
- try
- {
- using (DirectoryEntry deRoot = new DirectoryEntry(PATH))
- {
- using (DirectoryEntry de = deRoot.Children.Add(user.name, "User"))
- {
- de.Properties["FullName"].Add(user.fullname); // 用户全称
- de.Invoke("SetPassword", user.password); // 用户密码
- de.Invoke("Put", "Description", user.description);// 用户详细描述
- de.Invoke("Put", "UserFlags", 66049); // 密码永不过期
- de.CommitChanges();
- return "OK";
- }
- }
- }
- catch (Exception ex)
- {
- return ex.Message;
- }
- }
- /// <summary>
- /// 移除用户
- /// </summary>
- /// <param name="name"></param>
- /// <returns></returns>
- public string RemoveUser(string name)
- {
- try
- {
- using (DirectoryEntry deRoot = new DirectoryEntry(PATH))
- {
- using (DirectoryEntry user = deRoot.Children.Find(name, "User"))
- {
- if (user != null)
- dir.Children.Remove(user);
- return "OK";
- }
- }
- }
- catch (Exception ex)
- {
- return ex.Message;
- }
- }
- /// <summary>
- /// 修改用户密码
- /// </summary>
- /// <param name="user"></param>
- /// <returns></returns>
- public string ChangePassword(User user)
- {
- try
- {
- using (DirectoryEntry deRoot = new DirectoryEntry(PATH))
- {
- using (DirectoryEntry de = dir.Children.Find(user.name, "User"))
- {
- de.Invoke("SetPassword", new object[] { user.password });
- de.CommitChanges();
- return "OK";
- }
- }
- }
- catch (Exception ex)
- {
- return ex.Message;
- }
- }
- }
- }
4. webapi 下注意项
在 webapi 下, 如果使用 DirectoryEntry 类, 需添加
Microsoft.Web.Infrastructure
的引用.
在 web.config 中, 需增加如下的配置节, 否则会报拒绝访问的错误.
- <system.web>
- <identity impersonate="true" />
- </system.web>
来源: http://www.bubuko.com/infodetail-2671530.html