活动目录(AD)
Active Directory 是用于 Windows Server 的目录服务
它存储着网络上各种对象的有关信息并使该信息易于管理员和用户查找及使用
Active Directory 目录服务使用结构化的数据存储作为目录信息的逻辑层次结构的基础
通过登录验证以及目录中对象的访问控制将安全性集成到 Active Directory 中
目录服务如 Active Directory提供了用于存储目录数据并使该数据可由网络用户和管理员使用的方法
例如Active Directory 存储了有关用户帐户的信息如名称密码电话号码等并允许相同网络上的其他已授权用户访问该信息
LDAP
LDAP是轻量目录访问协议英文全称是Lightweight Directory Access Protocol
LDAP是基于X标准的
LDAP 仅通过使用原始 X目录存取协议 (DAP) 的功能子集而减少了所需的系统资源消耗
与X不同LDAP支持TCP/IP这对访问Internet是必须的
LDAP和关系数据库是两种不同层次的概念后者是存贮方式(同一层次如网格数据库对象数据库)前者是存贮模式和访问协议
LDAP是一个比关系数据库抽象层次更高的存贮概念与关系数据库的查询语言SQL属同一级别
ADSI
在Delphi中可以使用微软的ADSI(活动目录服务接口)来访问活动目录
ADSI是一组以COM接口的形式提供目录服务的是为基于目录服务提供的通用接口
一些标准的ADSI提供者(Provider)有WinNTIISLDAP和NDS
可以通过ADSI存取四种网络目录结构
WinNT (Microsoft SAM 数据库)LDAP (轻量目录存取协议)NDS (NetWare目录服务)和NWCOMPAT(Novell NetWare x)
ADSI可以使Windows NT 管理员的工作变得轻松
ADSI支持管理员执行一些一般的管理任务比如添加新用户管理打印机安全设定和控制NT域
因为ADSI使用COM接口任何支持COM的编程语言像DelphiBCBVBVC等都可以调用ADSI
如在Delphi中调用ADSI则需要引入活动目录类型库
操作如下
在IDE中Project>Import Type Library
选择Active Ds Type Library(Version )单击Create Unit
Delphi会做相应的封装生成ActiveDs_TLBpas文件
Uses ActiveDs_TLB就可以在Delphi程序中使用ADSI了
JAVA+LDAP访问Window Server AD
package ADOper;
import javautilHashtable;
import javaxnamingContext;
import javaxnamingldapLdapContext;
import javaxnamingldapInitialLdapContext;
import javaxnamingNamingEnumeration;
import javaxnamingdirectorySearchControls;
import javaxnamingdirectorySearchResult;
import javaxnamingNamingException;
import javaxnamingdirectoryAttribute;
import javaxnamingdirectoryAttributes;
import javautilEnumeration;
public class ADOperTest {
public ADOperTest() {
}
public void GetADInfo() {
Hashtable HashEnv = new Hashtable();
String LDAP_URL = ldap://:; //LDAP访问地址
//String adminName = CN=OAWebUserCN=UsersDC=HebmcDC=com;//AD的用户名
String adminName = Hebmc\\OAWebUser; //注意用户名的写法domain\User 或
adminName = ; //注意用户名的写法domain\User 或
String adminPassword = chenzuooaup; //密码
HashEnvput(ContextSECURITY_AUTHENTICATION simple); //LDAP访问安全级别
HashEnvput(ContextSECURITY_PRINCIPAL adminName); //AD User
HashEnvput(ContextSECURITY_CREDENTIALS adminPassword); //AD Password
HashEnvput(ContextINITIAL_CONTEXT_FACTORYcomsunjndildapLdapCtxFactory); //LDAP工厂类
HashEnvput(ContextPROVIDER_URL LDAP_URL);
try {
LdapContext ctx = new InitialLdapContext(HashEnv null);
SearchControls searchCtls = new SearchControls(); //Create the search controls
searchCtlssetSearchScope(SearchControlsSUBTREE_SCOPE); //Specify the search scope
String searchFilter = objectClass=User; //specify the LDAP search filter
//String searchFilter = objectClass=organizationalUnit;//specify the LDAP search filter
String searchBase = DC=HebmcDC=com; //Specify the Base for the search//搜索域节点
int totalResults = ;
//Specify the attributes to return
//String returnedAtts[] = {memberOf};//定制返回属性
String returnedAtts[] = {
url whenChanged employeeID name userPrincipalName
physicalDeliveryOfficeName departmentNumber telephoneNumber
homePhone mobile department sAMAccountName whenChanged
mail}; //定制返回属性
searchCtlssetReturningAttributes(returnedAtts); //设置返回属性集
//Search for objects using the filter
NamingEnumeration answer = ctxsearch(searchBase searchFiltersearchCtls);
while (answerhasMoreElements()) {
SearchResult sr = (SearchResult) answernext();
Systemoutprintln(************************************************);
Systemoutprintln(srgetName());
Attributes Attrs = srgetAttributes();
if (Attrs != null) {
try {
for (NamingEnumeration ne = AttrsgetAll(); nehasMore(); ) {
Attribute Attr = (Attribute) nenext();
Systemoutprintln( AttributeID= + AttrgetID()toString());
//读取属性值
for (NamingEnumeration e = AttrgetAll(); ehasMore();totalResults++) {
Systemoutprintln( AttributeValues= + enext()toString());
}
Systemoutprintln( );
//读取属性值
Enumeration values = AttrgetAll();
if (values != null) { // 迭代
while (valueshasMoreElements()) {
Systemoutprintln( AttributeValues= + valuesnextElement());
}
}
Systemoutprintln( );
}
}
catch (NamingException e) {
Systemerrprintln(Throw Exception : + e);
}
}
}
Systemoutprintln(Number: + totalResults);
ctxclose();
}
catch (NamingException e) {
eprintStackTrace();
Systemerrprintln(Throw Exception : + e);
}
}
public static void main(String args[]) {
ADOperTest ad = new ADOperTest();
adGetADInfo();
}
}
备注
使用LADP访问AD注意用户名的写法domain\User 或
如用户名不正确则可能会出现如下异常
javaxnamingAuthenticationException: [LDAP: error code : LdapErr: DSIDC comment: AcceptSecurityContext error data vece
Delphi使用WinNT Provider访问Window Server AD
unit Unt_AD;
interface
uses
Windows Messages SysUtils Variants Classes Graphics Controls Forms
Dialogs StdCtrls ComCtrls ActiveDs_TLB ActiveX ComObj;
type
TMainFrm = class(TForm)
grp: TGroupBox;
cbUseLogin: TCheckBox;
lbl: TLabel;
ADSIUsername: TEdit;
lbl: TLabel;
ADSIPassword: TEdit;
ADSIDomainName: TEdit;
btn: TButton;
lbl: TLabel;
GroupListView: TListView;
ComputerListView: TListView;
SeverListView: TListView;
UserListView: TListView;
lbl: TLabel;
lbl: TLabel;
Label: TLabel;
lbl: TLabel;
procedure btnClick(Sender: TObject);
private
{ Private declarations }
procedure GetDomainInformation(Domain: IADsContainer);
procedure AddUserToList(ADsObj:IADs);
procedure AddGroupToList(ADsObj:IADs);
procedure AddComputerToList(ADsObj:IADs);
public
{ Public declarations }
end;
//连接 Win NT 目录服务就是找到域控制器然后绑定到相应的对象上
//绑定可以通过 ADsGetObject 或 ADsOpenObject 函数来实现
//第一个函数使用登录用户缺省的信任级别
//第二个函数允许开发者指定特殊的安全信任机制来绑定 ADSI 对象
//缺省条件下ADsGetObject函数根据当前用户进行安全认证
function ADsGetObject(lpszPathName: PWideChar; //第一个参数是对象的路径名
const riid: TIID; //第二个参数是对象的接口标识符
out obj): HResult; stdcall; external activedsdll;// 第三个参数用于返回得到的被请求的接口指针
//ADsOpenObject 函数在不同的安全认证机制下绑定 ADSI 对象
//它主要是通过调用参数返回的用户名和口令来认证的
function ADsOpenObject(lpszPathName: PWideChar; //第一个参数是对象的路径名
lpszUserName: PWideChar; //第二个参数是调用者提供的用户名
lpszPassword: PWideChar; //第三个参数是调用者提供的口令
dwReserved: LongInt; //第四个参数是一个保留的 provider 标识用来确定绑定的认证方法
const riid: TIID; //第五个参数是请求接口的接口标识符
out obj): HResult; stdcall; external activedsdll; //最后一个参数用来返回请求的接口指针
var
MainFrm: TMainFrm;
implementation
{$R *dfm}