并提高数据的一致性,在微软的活动目录中

  • 栏目:编程 时间:2020-04-06 00:02
<返回列表

如果使用活动目录(Active Directory)代替在数据库表中建立账号, 你可以使用原来Windows网络中的账号.LDAP, 轻量级目录访问协议(Lightweight Directory Access Protocol), 是用来访问微软的活动目录等目录服务器(DS, Directory Server)的协议. PHP默认支持LDAP.下面是使用LDAP进行用户身份验证的PHP程序. 在微软的活动目录中, 用户的唯一标识是samaccountname, 有些DS是uid. 方法是:

这一周做LDAP做得头都大了。现在终于有点头绪了,记录一下,以备后用。

  1. 用有权限的账号的dn(形如 cn=user_name,ou=web,dc=ideawu,dc=com)连接LDAP Server. 2. 根据登录用户的名字查询其dn. 3. 用该dn连接LDAP Server. 如果连接上就是登录成功. 注意! 微软的活动目录服务器可以使用空账号连接成功(设置问题? 默认? 特例?)!$userid = $_POST[''userid''];$user_password = $_POST[''password''];if($userid $user_password){// config// $ldap_server = ideawu.com;// $ldap_admin = user_name;// $ldap_password = xxx;// $base_cn = ou=web,dc=ideawu,dc=com;$conn = ldap_connect($ldap_server);if(!$conn){die(brConnection LDAP server error);}$bind = ldap_bind($conn, $ldap_admin, $ldap_password);if(!$bind){die(brBind LDAP server error);}$filter = ''samaccountname='' . $userid;$attributes = array(''mail'');$result = ldap_search($conn, $base_dn, $filter, $attributes);$info = ldap_get_entries($conn, $result);if(!$result){die(brSearch failed);}if($info[count] != 0){$user_dn = $info[0][dn];unset($bind2);$bind2 = @ldap_bind($conn, $user_dn, $user_password);if($bind2){// Login done. Set session}}ldap_close($conn);}

 

LDAP是什么?
LDAP是轻量级目录访问协议,英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP.
一般用来构建集中的身份验证系统可以减少管理成本,增强安全性,避免数据复制的问题,并提高数据的一致性。

ActiveDirectory是什么?
Active Directory存储了有关网络对象的信息,并且让管理员和用户能够轻松地查找和使用这些信息。Active Directory使用了一种结构化的数据存储方式,并以此作为基础对目录信息进行合乎逻辑的分层组织。
①基础网络服务:包括DNS、WINS、DHCP、证书服务等。

 

②服务器及客户端计算机管理:管理服务器及客户端计算机账户,所有服务器及客户端计算机加入域管理并实施组策略。

 

③用户服务:管理用户域账户、用户信息、企业通讯录(与电子邮件系统集成)、用户组管理、用户身份认证、用户授权管理等,按省实施组管理策略。

 

④资源管理:管理打印机、文件共享服务等网络资源。

 

⑤桌面配置:系统管理员可以集中的配置各种桌面配置策略,如:界面功能的限制、应用程序执行特征限制、网络连接限制、安全配置限制等。

 

s⑥应用系统支撑:支持财务、人事、电子邮件、企业信息门户、办公自动化、补丁管理、防病毒系统等各种应用系统。


概念都是搜出来的,不是一般的抽象。这也是我花了近一周时间才弄懂一点的原因所在。
我的理解是可以把mirectory的ActiveDirectory当作一个LDAP服务器,提供LDAP验证服务。当然其他平台或公司也有自己的ldap服务器。如sun,ibm,等的。

我的需求是在EOS开发平台(基于EclipseJAVA工作流)上通过内嵌的开源ABFrame(权限管理系统)实现LDAP验证,
进而实现SSO。

找到了LDAP的配置文件后经过查找资料无论如何也通不过验证,还跟了很深的代码,JNDI的资料也查了很多,无果。

 

无奈,微软自己家东西,就试着用.net写了个程序,没有什么障碍,很简单就通过了登陆验证。代码如下:

韦德体育 1韦德体育 2ldap C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.Configuration;
using System.Text.RegularExpressions;

namespace ldapcs
{
class Program
{
staticvoid Main(string[] args)
{
string path ="LDAP://192.168.137.210:389/ou=pet,dc=abc,dc=com ";
string username ="uname";
string pwd ="upwd";
string domain ="abc.com";

LdapAuthentication ldap =new LdapAuthentication(path);
Console.WriteLine( ldap.IsAuthenticated(domain, username, pwd));
Console.WriteLine(ldap.GetGroups());
}

publicclass LdapAuthentication
{
privatestring _path;
privatestring _filterAttribute;

public LdapAuthentication(string path)
{
_path = path;
}

publicbool IsAuthenticated(string domain, string username, string pwd)
{
string domainAndUsername = domain +@""+ username;
DirectoryEntry entry =new DirectoryEntry(_path, username, pwd);

try
{
//Bind to the native AdsObject to force authentication.
object obj = entry.NativeObject;

DirectorySearcher search =new DirectorySearcher(entry);

search.Filter ="(SAMAccountName="+ username +")";
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();

if (null== result)
{
returnfalse;
}

//Update the new path to the user in the directory.
_path = result.Path;
_filterAttribute = (string)result.Properties["cn"][0];
}
catch (Exception ex)
{
thrownew Exception("Error authenticating user. "+ ex.Message);
}

returntrue;
}

publicstring GetGroups()
{
DirectorySearcher search =new DirectorySearcher(_path);
search.Filter ="(cn="+ _filterAttribute +")";
//search.SearchRoot = "PET";
StringBuilder groupNames =new StringBuilder();

try
{
SearchResult result = search.FindOne();
int propertyCount = result.Properties["memberOf"].Count;
string dn;
int equalsIndex, commaIndex;

for (int propertyCounter =0; propertyCounter < propertyCount; propertyCounter++)
{
dn = (string)result.Properties["memberOf"][propertyCounter];
equalsIndex = dn.IndexOf("=", 1);
commaIndex = dn.IndexOf(",", 1);
if (-1== equalsIndex)
{
returnnull;
}
groupNames.Append(dn.Substring((equalsIndex +1), (commaIndex - equalsIndex) -1));
groupNames.Append("|");
}
}
catch (Exception ex)
{
thrownew Exception("Error obtaining group names. "+ ex.Message);
}
return groupNames.ToString();
}
}

///<summary>
/// 验证AD用户是否登录成功
///</summary>
///<param name="domain"></param>
///<param name="userName"></param>
///<param name="password"></param>
///<returns></returns>
publicstaticbool TryAuthenticate(string domain, string userName, string password)
{
bool isLogin =false;
try
{
DirectoryEntry entry =new DirectoryEntry(string.Format("LDAP://{0}", domain), userName, password);
entry.RefreshCache();
isLogin =true;
}
catch
{
isLogin =false;
}
return isLogin;
}
}
}

 

再回头去用abframe的东西,还是没有结果。于是再找一个java验证的例子,还是可以通过验证

韦德体育 3韦德体育 4代码

/**
*
* @author icuit
*/
import java.util.Hashtable;
import java.util.Enumeration;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls ;
import javax.naming.NamingEnumeration;
import javax.naming.directory.SearchResult;

publicclass LDAPtest {

publicstaticvoid main(String[] args) {
LDAPtest ldap=new LDAPtest();
ldap.init();
}
publicvoid init(){
DirContext ctx =null;
Hashtable env =new Hashtable();
env.put(Context.INITIAL_韦德体育 ,CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://192.168.137.210:389/");//连接LDAP的URL和端口

//env.put(Context.SECURITY_AUTHENTICATION, "simple");//以simple方式发送
env.put(Context.SECURITY_PRINCIPAL, "cn=uname,ou=PET,DC=abc,DC=com");//用户名
env.put(Context.SECURITY_CREDENTIALS, "upwd");//密码
String baseDN="ou=PET,DC=abc,DC=com";//查询区域
String filter="(&(objectClass=person))";//条件查询

try{
ctx =new InitialDirContext(env);//连接LDAP服务器
System.out.println("Success");
SearchControls constraints =new SearchControls();//执行查询操作
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration en=ctx.search(baseDN, filter, constraints);
if(en==null){
System.out.println("There have no value");
}else{
while(en.hasMoreElements()){

Object obj=en.nextElement();
if(obj instanceof SearchResult){
SearchResult sr=(SearchResult) obj;
String cn=sr.getName();

System.out.println("cccccc: "+cn);
}
}
}

}catch(javax.naming.AuthenticationException e){
System.out.println(e.getMessage());
}catch(Exception e){
System.out.println("erro:"+e);
}
}
}

于是又去跟abframe的代码,并重新检查文件,并查了一些关于LDAP验证参数的资料。终于可以验证,总结如下:

ldap验证有几个比较重要的参数:
ldap_base_provider_url, 
ldap服务器的地址及端口,如:

ldap_security_principal,  
用来查询验证ldap服务的用户
如 cn=uname,ou=pet,dc=abc,dc=com,或者有可能是cn=uadmin,cn=users,dc=abc,dc=com
这里是最最关键的地方,我也是在这方面花费了最多的时间,
如果服务器的域名是 abc.com 那么就要有 dc=abc,dc=com,其他情况以此类推
cn是指的用户名,但是这里有两种情况,一种是cn=uname,ou=pet,另一种是cn=uadmin,cn=users
我的猜测是如果在windows Active Directory的内建分组users下的用户则用第二种
如果是在windows Active Directory的自建分组,如组名为PET,则用第一种

dap_security_credentials,
用来查询验证ldap服务的密码,与ldap_security_principal配对 如 f34dgd

这里需要重点说明一下,ldap_security_principal与ldap_security_principal所指定的用户和密码并不是
最终要验证的用户,而是一个用来查询所要验证的用户是否存在的用户。

ldap_base_dn,             ldap服务的验证基址,因为ldap是基于目录,也就有层次关系,如ou=PET,dc=intasect,dc=local
这里是需要验证的用户目录,至于参数的解释同ldap_security_principal

ldap_auth_search_filter
查询验证用户的搜索条件,一般是(objectClass=person),是什么意思我也没细去研究

ldap_auth_method
身份验证方式, bind 或 password-compare
bind 基于绑定用户身份检查,我这里采用的第一种,也许是因为windows AD是这一种,另一种无法通过
password-compare 基于加密算法,采用密码比较方法

ldap_auth_password_encryption_algorithm
密码加密方法 MD5,SHA等。
我用的是MD5

以上参数错一个可能就通不过验证,所以参数的正确性是关键。

这里留下一些参考的资料
1,LDAP验证常见的错误代码

javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 52e, vece
意思是用户名或密码错误

javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr: DSID-0C090AE2, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece
大概是查询的目录无效,应该是ou设置错误

 

2,参考网站


 

3,windows active directory在win2003上的安装方法
其实安装AD的过程也就是把此机器升级为域控制器的过程,有一点要提醒的是在升级域之前一定要备份自建账户信息
否则当降级为普通计算机时所有自建账户信息将丢失。切记。

 

4,在ActiveDirectory新建组,新建用户,配置域名

希望有其他朋友遇到同样问题时少走弯路。

上一篇:php分页程序及简单实例说明 下一篇:韦德体育以后建立编辑数据库可以靠它了

更多阅读

并提高数据的一致性,在微软的活动目录

编程 2020-04-06
如果使用活动目录(Active Directory)代替在数据库表中建立账号,你可以使用原来Windows网络中的账号...
查看全文

php生成xml 类

编程 2020-04-06
?phpclass majax extends blogadmin {var $result = '?xml version=1.0encoding=gb2312?';function majax($db) {$this-db = $db;$...
查看全文

韦德体育以后建立编辑数据库可以靠它了

编程 2020-04-06
学习目的:学会构建数据库 在ASP中,如果是ACCESS数据库你可以直接打开ACCESS来编辑MDB文件,如...
查看全文

友情链接: 网站地图

Copyright © 2015-2019 http://www.koi-bumi.com. 韦德体育有限公司 版权所有