概要
活動目錄(Active Directory)是面向Windows Standard Server、Windows Enterprise Server以及 Windows Datacenter Server的目錄服務。(Active Directory不能運行在Windows Web Server上,但是可以通過它對運行Windows Web Server的計算機進行管理。)Active Directory存儲了有關網絡對象的信息,并且讓管理員和用戶能夠輕松地查找和使用這些信息。Active Directory使用了一種結構化的數據存儲方式,并以此作為基礎對目錄信息進行合乎邏輯的分層組織。
Microsoft Active Directory 服務是Windows 平臺的核心組件,它為用戶管理網絡環境各個組成要素的標識和關系提供了一種有力的手段。
功能
活動目錄(Active Directory)主要提供以下功能:
①基礎網絡服務:包括DNS、WINS、DHCP、證書服務等。
②服務器及客戶端計算機管理:管理服務器及客戶端計算機賬戶,所有服務器及客戶端計算機加入域管理并實施組策略。
③用戶服務:管理用戶域賬戶、用戶信息、企業通訊錄(與電子郵件系統集成)、用戶組管理、用戶身份認證、用戶授權管理等,按省實施組管理策略。
④資源管理:管理打印機、文件共享服務等網絡資源。
⑤桌面配置:系統管理員可以集中的配置各種桌面配置策略,如:界面功能的限制、應用程序執行特征限制、網絡連接限制、安全配置限制等。
⑥應用系統支撐:支持財務、人事、電子郵件、企業信息門戶、辦公自動化、補丁管理、防病毒系統等各種應用系統。
LDAP
? LDAP是輕量目錄訪問協議,英文全稱是Lightweight Directory Access Protocol。?
? LDAP是基于X.500標準的。?
? LDAP 僅通過使用原始 X.500目錄存取協議 (DAP) 的功能子集而減少了所需的系統資源消耗。?
? 與X.500不同,LDAP支持TCP/IP,這對訪問Internet是必須的。?
? LDAP和關系數據庫是兩種不同層次的概念,后者是存貯方式(同一層次如網格數據庫,對象數據庫),前者是存貯模式和訪問協議。?
? LDAP是一個比關系數據庫抽象層次更高的存貯概念,與關系數據庫的查詢語言SQL屬同一級別。
?
開發功能
先看看System.DirectoryServices的代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
namespace
System.DirectoryServices
{
????
[DSDescription(
"DirectoryEntryDesc"
)]
????
[TypeConverter(
typeof
(DirectoryEntryConverter))]
????
[SecurityPermission(SecurityAction.Assert, Flags = SecurityPermissionFlag.UnmanagedCode)]
????
[EnvironmentPermission(SecurityAction.Assert, Unrestricted =
true
)]
????
[DirectoryServicesPermission(SecurityAction.LinkDemand, Unrestricted =
true
)]
????
public
class
DirectoryEntry : Component
????
{
????????
[DirectoryServicesPermission(SecurityAction.Demand, Unrestricted =
true
)]
????????
public
DirectoryEntry();
?
????????
[DirectoryServicesPermission(SecurityAction.Demand, Unrestricted =
true
)]
????????
public
DirectoryEntry(
string
path);
?
????????
[DirectoryServicesPermission(SecurityAction.Demand, Unrestricted =
true
)]
????????
public
DirectoryEntry(
string
path,
string
username,
string
password);
?
????????
[DirectoryServicesPermission(SecurityAction.Demand, Unrestricted =
true
)]
????????
public
DirectoryEntry(
string
path,
string
username,
string
password, AuthenticationTypes authenticationType);
?
????????
[DirectoryServicesPermission(SecurityAction.Demand, Unrestricted =
true
)]
????????
public
DirectoryEntry(
object
adsObject);
?
????????
[DefaultValue(AuthenticationTypes.Secure)]
????????
[DSDescription(
"DSAuthenticationType"
)]
????????
public
AuthenticationTypes AuthenticationType {
get
;
set
; }
?
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
[DSDescription(
"DSChildren"
)]
????????
[Browsable(
false
)]
????????
public
DirectoryEntries Children {
get
; }
?
????????
[DSDescription(
"DSGuid"
)]
????????
[Browsable(
false
)]
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
public
Guid Guid {
get
; }
?
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
[Browsable(
false
)]
????????
[DSDescription(
"DSObjectSecurity"
)]
????????
public
ActiveDirectorySecurity ObjectSecurity {
get
;
set
; }
?
????????
[DSDescription(
"DSName"
)]
????????
[Browsable(
false
)]
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
public
string
Name {
get
; }
?
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
[DSDescription(
"DSNativeGuid"
)]
????????
[Browsable(
false
)]
????????
public
string
NativeGuid {
get
; }
?
????????
[DSDescription(
"DSNativeObject"
)]
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
[Browsable(
false
)]
????????
public
object
NativeObject {
get
; }
?
????????
[DSDescription(
"DSParent"
)]
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
[Browsable(
false
)]
????????
public
DirectoryEntry Parent {
get
; }
?
????????
[DefaultValue(
null
)]
????????
[Browsable(
false
)]
????????
[DSDescription(
"DSPassword"
)]
????????
public
string
Password {
set
; }
?
????????
[SettingsBindable(
true
)]
????????
[DefaultValue(
""
)]
????????
[TypeConverter(
"System.Diagnostics.Design.StringValueConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
)]
????????
[DSDescription(
"DSPath"
)]
????????
public
string
Path {
get
;
set
; }
?
????????
[DSDescription(
"DSProperties"
)]
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
[Browsable(
false
)]
????????
public
PropertyCollection Properties {
get
; }
?
????????
[DSDescription(
"DSSchemaClassName"
)]
????????
[Browsable(
false
)]
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
public
string
SchemaClassName {
get
; }
?
????????
[Browsable(
false
)]
????????
[DSDescription(
"DSSchemaEntry"
)]
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
public
DirectoryEntry SchemaEntry {
get
; }
?
????????
[DefaultValue(
true
)]
????????
[DSDescription(
"DSUsePropertyCache"
)]
????????
public
bool
UsePropertyCache {
get
;
set
; }
?
????????
[DSDescription(
"DSUsername"
)]
????????
[DefaultValue(
null
)]
????????
[Browsable(
false
)]
????????
[TypeConverter(
"System.Diagnostics.Design.StringValueConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
)]
????????
public
string
Username {
get
;
set
; }
?
????????
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
????????
[ComVisible(
false
)]
????????
[DSDescription(
"DSOptions"
)]
????????
[Browsable(
false
)]
????????
public
DirectoryEntryConfiguration Options {
get
; }
?
????????
public
void
Close();
????????
public
void
CommitChanges();
????????
public
DirectoryEntry CopyTo(DirectoryEntry newParent);
????????
public
DirectoryEntry CopyTo(DirectoryEntry newParent,
string
newName);
????????
public
void
DeleteTree();
????????
protected
override
void
Dispose(
bool
disposing);
????????
public
static
bool
Exists(
string
path);
????????
public
object
Invoke(
string
methodName,
params
object
[] args);
?
????????
[ComVisible(
false
)]
????????
public
object
InvokeGet(
string
propertyName);
?
????????
[ComVisible(
false
)]
????????
public
void
InvokeSet(
string
propertyName,
params
object
[] args);
?
????????
public
void
MoveTo(DirectoryEntry newParent);
????????
public
void
MoveTo(DirectoryEntry newParent,
string
newName);
????????
public
void
RefreshCache();
????????
public
void
RefreshCache(
string
[] propertyNames);
????????
public
void
Rename(
string
newName);
????
}
}
|
?
在Active Directory中搜索?
1.SearchRoot?
指定搜索從哪里開始,如當前節點等?
1
2
|
DirectorySearcher search =
new
DirectorySearcher();
search.SearchRoot = de;
|
?
2.過濾器?
過濾條件是用雙引號引起來的括號中的內容如"(&(objectClass=user)(|(description=Auth*)(name=m*)))"?
1
|
searcher.Filter=
"(&(objectClass=user)(|(description=Auth*)(name=m*)))"
|
?
3.搜索范圍?
1
|
search.SearchScope = SearchScope.Subtree;
|
?
取值如下:Subtree,Base(只搜索對象中的屬性,至多可以得到一個對象),OneLevel(在基對象的子集中搜索,基對象不搜索)?
4.加載的屬性PropertiesToLoad?
對象的很多屬性都不太重要,此處定義了加載到緩存中的對象屬性,若沒有指定,默認是對象的Path和Name屬性?
1
2
3
4
|
search.PropertiesToLoad.Add(
"name"
);
search.PropertiesToLoad.Add(
"description"
);
search.PropertiesToLoad.Add(
"giveName"
);
search.PropertiesToLoad.Add(
"wWWWHomePage"
);
|
?
5.對結果進行排序,Sort函數有兩個參數,第一個是要排序的字段,第二個為排序方式SortOption有兩個值,Ascending和Descending?
1
|
search.Sort =
new
SortOption(
"givenName"
,SortDirection.Ascending);
|
?
6.開始搜索,FindAll()查找返回一個SearchResultCollection,FindOne()返回一個簡單的SearchResult對象?
1
|
SearchResultCollection results = searcher.FindAll();
|
?
?
根據用戶帳號取得AD USER Information
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/// <summary>
???
/// 根據用戶賬號取得AD User對象
???
/// </summary>
???
/// <param name="account"></param>
???
/// <returns></returns>
???
public
DirectoryEntry GetUserByAccount(
string
account)
???
{
???????
DirectoryEntry user =
null
;
???????
using
(DirectoryEntry entry =
new
DirectoryEntry(
this
.LDAPAddress,
this
.AdminAccount,
this
.AdminPassword, AuthenticationTypes.Secure))
???????
{
???????????
using
(DirectorySearcher searcher =
new
DirectorySearcher(entry))
???????????
{
???????????????
searcher.Filter =
"(&(objectClass=user)(sAMAccountName="
+ account +
"))"
;
???????????????
searcher.SearchScope = SearchScope.Subtree;
???????????????
SearchResult searchResult = searcher.FindOne();
???????????????
if
(searchResult !=
null
)
???????????????
{
???????????????????
user = searchResult.GetDirectoryEntry();
???????????????
}
???????????
}
???????????
entry.Close();
???????
}
???????
return
user;
???
}
|
?
?
LDAPAddress的值
1
|
|
?
判斷用戶名字是否存在
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
//判斷用戶名字是否存在
????????
[DllImport(
"advapi32.dll"
, CharSet = CharSet.Auto, SetLastError =
true
, PreserveSig =
true
)]
????????
private
static
extern
bool
LookupAccountName(
??????????
string
lpSystemName,
string
lpAccountName,
??????????
System.IntPtr psid,
ref
int
cbsid,
??????????
StringBuilder domainName,
ref
int
cbdomainLength,
??????????
ref
int
use);
?
????????
public
bool
LookUpAccount(
string
accountName)
????????
{
????????????
//pointer an size for the SID
????????????
IntPtr sid = IntPtr.Zero;
????????????
int
sidSize = 0;
?
????????????
//StringBuilder and size for the domain name
????????????
StringBuilder domainName =
new
StringBuilder();
????????????
int
nameSize = 0;
?
????????????
//account-type variable for lookup
????????????
int
accountType = 0;
?
????????????
//get required buffer size
????????????
LookupAccountName(String.Empty, accountName, sid,
ref
sidSize, domainName,
ref
nameSize,
ref
accountType);
?
????????????
//allocate buffers
????????????
domainName =
new
StringBuilder(nameSize);
????????????
sid = Marshal.AllocHGlobal(sidSize);
?
????????????
//lookup the SID for the account
????????????
bool
result = LookupAccountName(String.Empty, accountName, sid,
ref
sidSize, domainName,
ref
nameSize,
ref
accountType);
????????????
if
(result)
????????????
{
????????????????
if
(accountName.ToLower().IndexOf(domainName.ToString().ToLower()) < 0)
????????????????
{
????????????????????
accountName = domainName +
"\\"
+ accountName;
????????????????
}
????????????????
//throw.Exception; .Show("The account is : " + accountName);
????????????
}
????????????
else
????????????
{
????????????????
//MessageBox.Show("Can't find the account.");
????????????
}
?
????????????
Marshal.FreeHGlobal(sid);
????????????
return
result;
????????
}
????
}
|
?
?
用戶賬號是否已處于活動狀態(非禁用)
/// <summary>?
/// 用戶賬號是否已處于活動狀態(非禁用)?
/// </summary>?
/// <param name="user"></param>?
/// <returns></returns>?
private bool IsUserActive(DirectoryEntry user)?
{?
??? int val = (int)user.Properties["userAccountControl"].Value;?
??? int flag = (int)(0x0002);?
??? int flagExists = val & flag;
??? if (flagExists > 0)?
??????? return false;?
??? else?
??????? return true;?
}
?
?
用戶登陸的實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/// <summary>
????
/// 用戶登錄驗證
????
/// </summary>
????
/// <param name="account">AD賬號</param>
????
/// <param name="password">密碼</param>
????
/// <returns>
????
/// <para>True:驗證成功</para>
????
/// <para>False:驗證失敗,如果this.Error不為空,則為異常信息</para>
????
/// </returns>
????
public
ADLoginResult Login(
string
account,
string
password)
????
{
????????
ADLoginResult result = ADLoginResult.UnSuccess;
????????
/* Check Accout Empty */
????????
if
(
string
.IsNullOrEmpty(account))
????????
{
????????????
result = ADLoginResult.UnSuccess;
????????????
return
result;
????????
}
????????
DirectoryEntry entry =
null
;
????????
DirectoryEntry user =
null
;
????????
try
????????
{
????????????
/* Check Account Exists */
????????????
entry =
this
.GetUserByAccount(account);
????????????
if
(entry !=
null
)
????????????
{
????????????????
using
(entry)
????????????????
{
????????????????????
/* Check Account Active */
????????????????????
if
(
this
.IsUserActive(entry))
????????????????????
{
????????????????????????
/* Check Password */
????????????????????????
using
(user =
new
DirectoryEntry(
this
.LDAPAddress, account, password, AuthenticationTypes.Secure))
????????????????????????
{
????????????????????????????
object
obj = user.NativeObject;
????????????????????????????
user.Close();
????????????????????????
}
????????????????????????
user =
null
;
????????????????????????
result = ADLoginResult.Success;
????????????????????
}
????????????????????
else
????????????????????
{
????????????????????????
result = ADLoginResult.Disabled;
????????????????????
}
????????????????????
entry.Close();
????????????????
}
????????????
}
????????????
else
????????????
{
????????????????
result = ADLoginResult.UnSuccess;
????????????
}
????????
}
????????
catch
(Exception ex)
????????
{
????????????
this
.Error = ex;
????????
}
????????
finally
????????
{
????????????
if
(user !=
null
)
????????????
{
????????????????
user.Close();
????????????????
user.Dispose();
????????????
}
????????????
if
(entry !=
null
)
????????????
{
????????????????
entry.Close();
????????????????
entry.Dispose();
????????????
}
????????
}
????????
return
result;
????
}
|
?
?
?
?
修改用戶密碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/// <summary>
???
/// 修改用戶密碼
???
/// </summary>
???
/// <param name="account">AD賬號</param>
???
/// <param name="oldPassword">舊密碼</param>
???
/// <param name="newPassword">新密碼</param>
???
/// <returns>
???
/// <para>ChangePwdResult.Success::修改成功</para>
???
/// <para>其它:修改失敗,如果this.Error不為空,則為異常信息</para>
???
/// </returns>
???
public
ChangePwdResult ChangePassword(
string
account,
string
oldPassword,
string
newPassword)
???
{
???????
ChangePwdResult result = ChangePwdResult.ChangePwdUnSuccess;
???????
/* Check Accout Empty */
???????
if
(
string
.IsNullOrEmpty(account))
???????
{
???????????
return
ChangePwdResult.UserNotExists;
???????
}
???????
DirectoryEntry user =
null
;
???????
/* Check Login */
???????
ADLoginResult loginSuccess =
this
.Login(account, oldPassword);
???????
try
???????
{
???????????
switch
(loginSuccess)
???????????
{
???????????????
case
ADLoginResult.Success:
???????????????????
#region [ Success ]
?
???????????????????
user =
this
.GetUserByAccount(account);
???????????????????
if
(user !=
null
)
???????????????????
{
???????????????????????
using
(user)
???????????????????????
{
???????????????????????????
bool
bImpSuccess =
false
;
???????????????????????????
if
(
this
.IsUseImpersonate)
???????????????????????????
{
???????????????????????????????
bImpSuccess =
this
._impersonation.BeginImpersonate();
???????????????????????????????
this
.ImpsersonateSuccess = bImpSuccess;
???????????????????????????????
if
(!bImpSuccess)
???????????????????????????????
{
???????????????????????????????????
/*
????????????????????????????????????
* 打開模擬情況下模擬失敗,先將結果默認為AdminLoginUnSuccess;
????????????????????????????????????
* 如果密碼修改成功,則會更新結果為Success;如果異常,
????????????????????????????????????
*/
???????????????????????????????????
result = ChangePwdResult.AdminLoginUnSuccess;
???????????????????????????????
}
???????????????????????????
}
?
???????????????????????????
int
userAccountControl = Convert.ToInt32(user.Properties[
"userAccountControl"
][0]);
?
???????????????????????????
/* Change Password */
???????????????????????????
user.Invoke(
"SetPassword"
,
new
object
[] { newPassword });
???????????????????????????
user.CommitChanges();
?
???????????????????????????
if
(
this
.IsUseImpersonate
???????????????????????????????
&& bImpSuccess)
???????????????????????????
{
???????????????????????????????
this
._impersonation.StopImpersonate();
???????????????????????????
}
?
???????????????????????????
user.Close();
???????????????????????????
result = ChangePwdResult.Success;
???????????????????????
}
???????????????????????
user =
null
;
???????????????????
}
???????????????????
else
???????????????????
{
???????????????????????
result = ChangePwdResult.UserNotExists;
???????????????????
}
?
???????????????????
#endregion
???????????????????
break
;
???????????????
case
ADLoginResult.UnSuccess:
???????????????????
result = ChangePwdResult.WrongOldPwd;
???????????????????
break
;
???????????????
case
ADLoginResult.Disabled:
???????????????????
result = ChangePwdResult.Disabled;
???????????????????
break
;
???????????????
default
:
???????????????????
result = ChangePwdResult.ChangePwdUnSuccess;
???????????????????
break
;
???????????
}
???????
}
???????
catch
(Exception ex)
???????
{
???????????
/* 模擬失敗情況下,返回模擬失敗 */
???????????
if
(result != ChangePwdResult.AdminLoginUnSuccess)
???????????
{
???????????????
result = ChangePwdResult.ChangePwdUnSuccess;
???????????
}
???????????
this
.Error = ex;
/* Get Error */
???????
}
???????
finally
???????
{
???????????
if
(user !=
null
)
???????????
{
???????????????
user.Close();
???????????????
user.Dispose();
???????????
}
???????
}
???????
return
result;
???
}
|
?
?
總結
AD開發主要用于SSO(單點登陸的開發),在office communication 開發中會用到.希望能對大家有幫助.
?
參考文獻
1、 http://baike.baidu.com/view/41408.htm
歡迎各位參與討論,如果覺得對你有幫助,請點擊
??? 推薦下,萬分謝謝.
作者: spring yang
出處: http://www.cnblogs.com/springyangwc/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
