使用webapi實(shí)現(xiàn)windows本地用戶管理

1. 引言

最近一段時間設(shè)計(jì)和實(shí)現(xiàn)公司內(nèi)部的基于OAuth2.0的統(tǒng)一身份認(rèn)證中心,經(jīng)梳理,公司部分自研系統(tǒng)可以使用OAuth2.0的方式進(jìn)行身份認(rèn)證伍伤,還有一部分系統(tǒng)無源代碼,未開放接口,使用windows用戶作為系統(tǒng)的用戶耘眨。面對這種情況,同時為實(shí)現(xiàn)一個中心一鍵開關(guān)賬戶的功能境肾,對于無源碼剔难、未開放接口、使用windows用戶作為系統(tǒng)用戶的系統(tǒng)奥喻,單獨(dú)開發(fā)接口程序偶宫,有數(shù)據(jù)庫的直接操作數(shù)據(jù)庫將賬號密碼同步至數(shù)據(jù)庫中;對于使用windows用戶作為系統(tǒng)用戶的系統(tǒng)环鲤,則在其部署的服務(wù)器上部署webapi接口纯趋,同步管理用戶和密碼。本文主要介紹的是C#對windows本地用戶的新增、刪除吵冒、修改密碼功能以及列出所有本地用戶的功能纯命。

2. Active Directory與DirectoryEntry 類

C#管理windows用戶,在百度上搜索到c#操作windows本地賬戶這樣一篇文章痹栖,主要是通過導(dǎo)入Netapi32.dll文件實(shí)現(xiàn)對windows本地賬戶的管理亿汞。而在之前有做過使用DirectoryEntry 類修改本地用戶密碼的功能,經(jīng)搜索揪阿,DirectoryEntry 類可封裝 Active Directory 域服務(wù)層次結(jié)構(gòu)中的節(jié)點(diǎn)或?qū)ο罅莆遥材軐?shí)現(xiàn)對用戶的新增、刪除以及其他功能南捂。

Active Directory
活動目錄(Active Directory)是面向Windows Standard Server吴裤、Windows Enterprise Server以及 Windows Datacenter Server的目錄服務(wù)。(Active Directory不能運(yùn)行在Windows Web Server上黑毅,但是可以通過它對運(yùn)行Windows Web Server的計(jì)算機(jī)進(jìn)行管理嚼摩。)Active Directory存儲了有關(guān)網(wǎng)絡(luò)對象的信息,并且讓管理員和用戶能夠輕松地查找和使用這些信息矿瘦。Active Directory使用了一種結(jié)構(gòu)化的數(shù)據(jù)存儲方式枕面,并以此作為基礎(chǔ)對目錄信息進(jìn)行合乎邏輯的分層組織。

可參考: Active Directory的基本概念

DirectoryEntry 類
DirectoryEntry類位于System.DirectoryServices表空間下缚去,可封裝 Active Directory 域服務(wù)層次結(jié)構(gòu)中的節(jié)點(diǎn)或?qū)ο蟪泵亍irectoryEntry類使用 Active Directory Services Interfaces (ADSI) 技術(shù)。 ADSI 是 Microsoft 為靈活的工具提供用于處理各種網(wǎng)絡(luò)提供程序的接口的集合易结。 ADSI 使管理員能夠定位和管理網(wǎng)絡(luò)上的資源相對容易地枕荞,而不考慮網(wǎng)絡(luò)的大小。

可參考:DirectoryEntry 類

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);//用戶詳細(xì)描述
                        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下注意項(xiàng)

  1. 在webapi下搞动,如果使用DirectoryEntry類躏精,需添加Microsoft.Web.Infrastructure的引用。
  2. 在web.config中鹦肿,需增加如下的配置節(jié)矗烛,否則會報(bào)拒絕訪問的錯誤。
 <system.web>    
    <identity impersonate="true" />
  </system.web>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末箩溃,一起剝皮案震驚了整個濱河市瞭吃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涣旨,老刑警劉巖歪架,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異霹陡,居然都是意外死亡和蚪,警方通過查閱死者的電腦和手機(jī)止状,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攒霹,“玉大人导俘,你說我怎么就攤上這事√尢#” “怎么了旅薄?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泣崩。 經(jīng)常有香客問我少梁,道長,這世上最難降的妖魔是什么矫付? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任凯沪,我火速辦了婚禮,結(jié)果婚禮上买优,老公的妹妹穿的比我還像新娘妨马。我一直安慰自己,他們只是感情好杀赢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布烘跺。 她就那樣靜靜地躺著,像睡著了一般脂崔。 火紅的嫁衣襯著肌膚如雪滤淳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天砌左,我揣著相機(jī)與錄音脖咐,去河邊找鬼。 笑死汇歹,一個胖子當(dāng)著我的面吹牛屁擅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播产弹,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼派歌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了取视?” 一聲冷哼從身側(cè)響起硝皂,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤常挚,失蹤者是張志新(化名)和其女友劉穎作谭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奄毡,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡折欠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锐秦。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡咪奖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酱床,到底是詐尸還是另有隱情羊赵,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布扇谣,位于F島的核電站昧捷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏罐寨。R本人自食惡果不足惜靡挥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸯绿。 院中可真熱鬧跋破,春花似錦、人聲如沸瓶蝴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舷手。三九已至饿悬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聚霜,已是汗流浹背狡恬。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蝎宇,地道東北人弟劲。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像姥芥,于是被迫代替她去往敵國和親兔乞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理凉唐,服務(wù)發(fā)現(xiàn)庸追,斷路器,智...
    卡卡羅2017閱讀 134,671評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,823評論 6 342
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,938評論 2 89
  • 哼著小曲徐風(fēng)去梳洗,遇見滿臉困倦且?guī)е谘廴Φ幕ㄐs簿训,不由地問道:“榮哥咱娶,你這是怎么了米间,昨晚沒睡好嗎?” “出...
    袋鼠小說閱讀 197評論 0 0
  • 不知道從什么時候開始膘侮,大家都變得敏感起來屈糊,氣氛變得怪怪的。 十一之前琼了,媽媽和爸爸來到我的城市看望阿姨逻锐,我媽就在我租...
    暮暮lynne閱讀 170評論 0 0