<?php
/**
* simple class for LDAP authentification
*
Copyright (C) 2013 Petr Palas This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* inspired by http://samjlevy.com/2010/09/php-login-script-using-ldap-verify-group-membership/
*/ namespace LDAP; use Exception; class auth {
/**
* url or ip of ldap server
* @var type string
*/
protected $ldap_host;
/**
* active directory DN
* @var type string
*/
protected $ldap_dn;
/**
* target user group
* @var type string
*/
protected $ldap_user_group;
/**
* manager group (shud contain users with management access)
* @var type string
*/
protected $ldap_manager_group;
/**
* contains email domain like "@somedomain.com"
* @var type string
*/
protected $ldap_usr_dom; /**
* countains connection resource
* @var type resource
*/
protected $ldap; /**
* contains status text
* if exeption is thrown msg contains this string
* @var type string
*/
public $status;
/**
* contains result array if ldap_search is succesfull
* @var type array
*/
public $result;
/**
* contains auth state 0=unathrized 1=authorized
* @var type int
*/
public $auth=0;
/**
* contains access level 0=none or unathorized 1=user 2=managment acc
* @var type int
*/
public $access=0; /**
* contains username after user init
* @var type string
*/
public $user; /**
* contain user password after user init
* @var type string
*/
protected $password; /**
* Exeptions code constants
*/
const ERROR_WRONG_USER_GROUP=2;
const ERROR_CANT_AUTH=1;
const ERROR_CANT_SEARCH=3;
const ERROR_IMG_DECODE=4;
const ERROR_CANT_CONNECT=5; /**
* loads passed configuration in case of the ldap_usr_dom it makes sure that this strings begins with '@'
* @param type $ldap_host
* @param type $ldap_dn
* @param type $ldap_user_group
* @param type $ldap_manager_group
* @param type $ldap_usr_dom
*/
function __construct($ldap_host,$ldap_dn,$ldap_user_group,$ldap_manager_group,$ldap_usr_dom) {
$this->ldap_host=$ldap_host;
$this->ldap_dn=$ldap_dn;
$this->ldap_user_group=$ldap_user_group;
$this->ldap_manager_group=$ldap_manager_group;
$this->ldap_usr_dom= '@'.trim($ldap_usr_dom,'@');
} /**
* well destructor :P
* just in case there is opened connection to LDAP while destructing this class
*/
public function __destruct() {
@ldap_unbind($this->ldap);
} /**
* dumps result array for debug enclosed in pre tag
* Wont terminate script!
*/
public function dump_resut() {
echo '<pre>';
print_r($this->result,FALSE);
echo '</pre>';
} /**
* Inits connection to LDAP server throws exeption on failure
* @return boolean
* @throws Exception
*/
protected function init_connection(){
$this->ldap=ldap_connect($this->ldap_host,3268);
if($this->ldap){
$this->status='connected :)';
ldap_set_option($this->ldap, LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($this->ldap, LDAP_OPT_REFERRALS,0);
}
else {
//TODO: PHP actualy dont check if there is LDAP present on the other end nor it will fail if target host is unreachable. So I need some work around that :(
$this->status='Cant connect to LDAP';
throw new Exception($this->status, self::ERROR_CANT_CONNECT);
}
return TRUE;
} public function userInit($user,$password) {
$this->user=$user;
$this->password=$password; return TRUE;
} /**
* Converts Binary string (like thumbnail from LDAP to base64 datastring for display
* @param type $file
* @param type $mime
* @return type base64 datastring
*/
protected function data_uri($file, $mime) {
$base64 = base64_encode($file);
return ('data:' . $mime . ';base64,' . $base64);
} /**
* Gets LDAP thumbnail img
* @param type $user
* @param type $password
* @param type $raw if TRUE method will return raw binary string instead of base64 encoded with mime
* @return type base64 datatring of the thumbnail
* @throws Exception
*/
public function getLDAPimg($user=null,$password=null,$raw=FALSE) {
$this->refreshCredentials($user, $password);
//since conection is one off we need to get it
$this->init_connection(); $bind = @ldap_bind($this->ldap, $user . $this->ldap_usr_dom, $password);//ldap_bind($this->ldap, $this->ldap_dn, $password); if($bind){
$filter = "(sAMAccountName=" . $user . ")";
$attr = array("thumbnailphoto");
$result = @ldap_search($this->ldap, $this->ldap_dn, $filter, $attr);
if($result==FALSE){
throw new Exception("Unable to search LDAP server. Reason: ". ldap_error($this->ldap), self::ERROR_CANT_SEARCH);
}
$entry= ldap_first_entry($this->ldap, $result); if ($entry) {
$info = @ldap_get_values_len($this->ldap, $entry, "thumbnailphoto");
if(!$info){
throw new Exception("Unable to decode thumbnail. Error: ". ldap_error($this->ldap), self::ERROR_IMG_DECODE);
}
//echo '<img src="'.$this->data_uri($info[0], 'image/png').'">';
} if(!$raw){
return $this->data_uri($info[0], 'image/png');
}
else{
return $info[0];
}
}
else {
// invalid name or password
$this->status='Cant authenticate for search on LDAP';
throw new Exception($this->status.' '. ldap_error($this->ldap), self::ERROR_CANT_AUTH);
}
ldap_unbind($this->ldap);
} /**
* Tries to authenticate suplied user with suplied pass
* @param type $user
* @param type $password
* @return boolean
* @throws Exception
*/
public function authenticate($user=null, $password=null) {
$this->refreshCredentials($user, $password);
//since conection is one off we need to get it
$this->init_connection(); // verify user and password
$bind = @ldap_bind($this->ldap, $user . $this->ldap_usr_dom, $password); if($bind) {
// valid
// check presence in groups
$filter = "(sAMAccountName=" . $user . ")";
$attr = array("memberof");
$result = @ldap_search($this->ldap, $this->ldap_dn, $filter, $attr);
if($result==FALSE){
throw new Exception("Unable to search LDAP server. Reason: ". ldap_error($this->ldap), self::ERROR_CANT_SEARCH);
}
$entries = ldap_get_entries($this->ldap, $result); //save result for future use
$this->result=$entries; $access = 0; // check groups
foreach($entries[0]['memberof'] as $grps) {
// is manager, break loop
if (strpos($grps, $this->ldap_manager_group)) { $access = 2; break; } // is user
if (strpos($grps, $this->ldap_user_group)) $access = 1;
} if ($access != 0) {
// establish result vars $this->status='Authenticated';
$this->access=$access;
$this->user= $user;
$this->auth=1;
return true;
} else {
// user has no rights
$this->access=$access;
$this->user= $user;
$this->auth=1;
$this->status='User exists but not part of the target group';
throw new Exception($this->status.' '. ldap_error($this->ldap), self::ERROR_WRONG_USER_GROUP);
} } else {
// invalid name or password
$this->status='Cant authenticate for search on LDAP';
throw new Exception($this->status.' '. ldap_error($this->ldap), self::ERROR_CANT_AUTH);
}
ldap_unbind($this->ldap);
} /**
* Saves new credentials if we got new or sets the old ones into referenced vars
* @param type $user Reference to var that shuld contain username or null
* @param type $password Reference to var that shuld contain password or null
*/
private function refreshCredentials(&$user,&$password) {
$newCredentials=TRUE;
//since we cant set those in param def
if($password===null){$password= $this->password;$newCredentials=FALSE;}
if($user===null){$user= $this->user;$newCredentials=FALSE;}
//store user pass and name for future use
if($newCredentials){$this->userInit($user, $password);}
} }

simple-LDAP-auth / ldap_auth.php的更多相关文章

  1. opennebula extend(expending) auth module ldap

    LDAP Authentication addon permits users to have the same credentials as in LDAP, so effectively cent ...

  2. LDAP Authentication for openNebula3.2

    LDAP Authentication 3.2 The LDAP Authentication addon permits users to have the same credentials as ...

  3. 《Linux菜鸟入门2》Ldap

    ldap网络帐号1.ldap是什么ldap目录服务认证,和windows活动目录类似,就是记录数据的一种方式 2.ldap客户端所需软件yum install sssd krb-workstation ...

  4. ldap 集成harbor

    harbor: 1.6 默认配置文件在harbor.cfg,我们可以先不添加配置,直接在harbor web界面进行配置(harbor 1.6 如果db 启动失败提示postgresql 数据目录已存 ...

  5. ldap集成grafana

    grafana版本: 5.0.3 grafana通过k8s方式安装,所以需将配置文件挂载过去. cat grafana-configmap.yaml apiVersion: v1 kind: Conf ...

  6. LDAP落地实战(二):SVN集成OpenLDAP认证

    上一篇文章我们介绍了LDAP的部署以及管理维护,那么如何接入LDAP实现账号统一认证呢?这篇文章将带你完成svn的接入验证 subversion集成OpenLDAP认证 系统环境:debian8.4 ...

  7. Mantis集成 LDAP 认证

    mantis的用户认证函数Authentication中相关有 $g_login_method MD5 LDAP PLAIN CRYPT CRYPT_FULL_SALT BASIC_AUTH Some ...

  8. LDAP方式连接AD获取用户信息

    LDAP资料介绍可以参考:http://wenku.baidu.com/view/262742f9f705cc17552709f9.html ldap访问AD域的的错误一般会如下格式: Ldap lo ...

  9. python实现ldap接入

    需要提前安装python-ldap模块 python接入ldap其实分了几个步骤: 1.使用一个管理员账户登陆到ldap 2.使用一个字段值是唯一的字段,去搜索到要验证用户的DN值(ldap搜索到的单 ...

  10. JAVA中使用LDAP登录的三种方式

    搜索中关于java 登录ldap,大部分会采用  cn=xxx,ou=xxx,dc=xxx的方式,此处的cn是用户的Display Name,而不是account,而且如果ou有多层,比如我们的OU就 ...

随机推荐

  1. HDU 5102 The K-th Distance

    题意:给你n-1条边,然后没两个节点的距离按照递增的顺序,求出前k项的和. 官方题解: 把所有边(u,v) 以及(v,u)放入一个队列,队列每弹出一个元素(u,v),对于所有与u相邻的点w,如果w!= ...

  2. Java的文件读写操作 <转>

    目录: file内存----输入流----程序----输出流----file内存 java中多种方式读文件 判断文件是否存在不存在创建文件 判断文件夹是否存在不存在创建文件夹 java 写文件的三种方 ...

  3. 转: 在创业公司使用C++

    from: http://oicwx.com/detail/827436 在创业公司使用C++ 2016-01-04开发资讯 James Perry和朋友创办了一家公司,主要是做基于云的OLAP多维数 ...

  4. 使用 ssh 连接github的方法说明(gitub的官方说法)

    https://help.github.com/articles/generating-an-ssh-key/

  5. Android中Intent传递对象的两种方法(Serializable,Parcelable)

    今天要给大家讲一下Android中 Intent中如何传递对象,就我目前所知道的有两种方法,一种是Bundle.putSerializable(Key,Object);另一种是 Bundle.putP ...

  6. CSS3实现几个常用的网页小效果

    主题 由于最近比较忙,自己也没有很充裕的时间可以去做比较丰富的分享.今晚我挤出时间来制作这几个很常用的CSS3网页小效果.最近写JS的时间比例比较多,不过我还是比较钟情于CSS3.所以我还是坚持分享一 ...

  7. 两种方式判断类的存在→className getAttribute

    通过className获取 var p = document.getElementsByTagName('p'); for(var i = 0;i <p.length;i++){ if(p[i] ...

  8. beanFactoory介绍

  9. kprobe原理解析(二)

    上一篇文章和大家简要说明了下kprobe到底应该怎样用,那么现在我们就揭开kprobe神秘的面纱,刨根问底,一睹kprobe的庐山真面目. kprobe的工作过程大致如下: 1)注册kprobe.注册 ...

  10. 13Spring_AOP编程(AspectJ)_后置通知

    后置通知和前置通知差不多.最大的特点是因为后置通知是运行在目标方法之后的,所以他可以拿到目标方法的运行的结果. 给出案例: 案例结构图: