• simple-LDAP-auth


      1 <?php
      2 /**
      3  * simple class for LDAP authentification
      4  * 
      5  Copyright (C) 2013 Petr Palas
      6 
      7 This program is free software; you can redistribute it and/or
      8 modify it under the terms of the GNU General Public License
      9 as published by the Free Software Foundation; either version 2
     10 of the License, or (at your option) any later version.
     11 
     12 This program is distributed in the hope that it will be useful,
     13 but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with this program; if not, write to the Free Software
     19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     20  * inspired by http://samjlevy.com/2010/09/php-login-script-using-ldap-verify-group-membership/
     21  */ 
     22 
     23 namespace LDAP;
     24 
     25 use Exception;
     26 
     27 class auth {
     28     /**
     29      * url or ip of ldap server
     30      * @var type string
     31      */
     32     protected $ldap_host;
     33     /**
     34      * active directory DN
     35      * @var type string
     36      */
     37     protected $ldap_dn;
     38     /**
     39      * target user group
     40      * @var type string
     41      */
     42     protected $ldap_user_group;
     43     /**
     44      * manager group (shud contain users with management access)
     45      * @var type string
     46      */
     47     protected $ldap_manager_group;
     48     /**
     49      * contains email domain like "@somedomain.com"
     50      * @var type string
     51      */
     52     protected $ldap_usr_dom;
     53     
     54     /**
     55      * countains connection resource
     56      * @var type resource
     57      */
     58     protected $ldap;
     59     
     60     /**
     61      * contains status text
     62      * if exeption is thrown msg contains this string
     63      * @var type string
     64      */
     65     public $status;
     66     /**
     67      * contains result array if ldap_search is succesfull
     68      * @var type array
     69      */
     70     public $result;
     71     /**
     72      * contains auth state 0=unathrized 1=authorized
     73      * @var type int
     74      */
     75     public $auth=0;
     76     /**
     77      * contains access level 0=none or unathorized 1=user 2=managment acc
     78      * @var type int
     79      */
     80     public $access=0;
     81     
     82     /**
     83      * contains username after user init
     84      * @var type string
     85      */
     86     public $user;
     87     
     88     /**
     89      * contain user password after user init
     90      * @var type string
     91      */
     92     protected $password;
     93     
     94     /**
     95      * Exeptions code constants
     96      */
     97     const ERROR_WRONG_USER_GROUP=2;
     98     const ERROR_CANT_AUTH=1;
     99     const ERROR_CANT_SEARCH=3;
    100     const ERROR_IMG_DECODE=4;
    101     const ERROR_CANT_CONNECT=5;
    102 
    103     /**
    104      * loads passed configuration in case of the ldap_usr_dom it makes sure that this strings begins with '@' 
    105      * @param type $ldap_host
    106      * @param type $ldap_dn
    107      * @param type $ldap_user_group
    108      * @param type $ldap_manager_group
    109      * @param type $ldap_usr_dom
    110      */
    111     function __construct($ldap_host,$ldap_dn,$ldap_user_group,$ldap_manager_group,$ldap_usr_dom) {
    112         $this->ldap_host=$ldap_host;
    113         $this->ldap_dn=$ldap_dn;
    114         $this->ldap_user_group=$ldap_user_group;
    115         $this->ldap_manager_group=$ldap_manager_group;
    116         $this->ldap_usr_dom=  '@'.trim($ldap_usr_dom,'@');
    117     }
    118     
    119     /**
    120      * well destructor :P
    121      * just in case there is opened connection to LDAP while destructing this class
    122      */
    123     public function __destruct() {
    124         @ldap_unbind($this->ldap);
    125     }
    126     
    127     /**
    128      * dumps result array for debug enclosed in pre tag
    129      * Wont terminate script!
    130      */
    131     public function dump_resut() {
    132         echo '<pre>';
    133         print_r($this->result,FALSE);
    134         echo '</pre>';
    135     }
    136     
    137     /**
    138      * Inits connection to LDAP server throws exeption on failure
    139      * @return boolean
    140      * @throws Exception
    141      */
    142     protected function init_connection(){
    143         $this->ldap=ldap_connect($this->ldap_host,3268);
    144         if($this->ldap){
    145             $this->status='connected :)';
    146             ldap_set_option($this->ldap, LDAP_OPT_PROTOCOL_VERSION,3);
    147             ldap_set_option($this->ldap, LDAP_OPT_REFERRALS,0);
    148         }
    149         else {
    150             //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 :(
    151             $this->status='Cant connect to LDAP';
    152             throw new Exception($this->status,  self::ERROR_CANT_CONNECT);
    153         }
    154         return TRUE;
    155     }
    156     
    157     public function userInit($user,$password) {
    158         $this->user=$user;
    159         $this->password=$password;
    160         
    161         return TRUE;
    162     }
    163     
    164     /**
    165      * Converts Binary string (like thumbnail from LDAP to base64 datastring for display
    166      * @param type $file
    167      * @param type $mime
    168      * @return type base64 datastring
    169      */
    170     protected function data_uri($file, $mime) {  
    171       $base64   = base64_encode($file); 
    172       return ('data:' . $mime . ';base64,' . $base64);
    173     }
    174     
    175     /**
    176      * Gets LDAP thumbnail img
    177      * @param type $user
    178      * @param type $password
    179      * @param type $raw if TRUE method will return raw binary string instead of base64 encoded with mime
    180      * @return type base64 datatring of the thumbnail
    181      * @throws Exception
    182      */
    183     public function getLDAPimg($user=null,$password=null,$raw=FALSE) {
    184         $this->refreshCredentials($user, $password);
    185         //since conection is one off we need to get it
    186         $this->init_connection();
    187         
    188         $bind = @ldap_bind($this->ldap, $user . $this->ldap_usr_dom, $password);//ldap_bind($this->ldap, $this->ldap_dn, $password);
    189         
    190         if($bind){
    191             $filter = "(sAMAccountName=" . $user . ")";
    192             $attr = array("thumbnailphoto");
    193             $result = @ldap_search($this->ldap, $this->ldap_dn, $filter, $attr);
    194             if($result==FALSE){
    195                 throw new Exception("Unable to search LDAP server. Reason: ".  ldap_error($this->ldap),  self::ERROR_CANT_SEARCH);
    196             }  
    197             $entry= ldap_first_entry($this->ldap, $result);
    198 
    199             if ($entry) {
    200                 $info = @ldap_get_values_len($this->ldap, $entry, "thumbnailphoto");
    201                 if(!$info){
    202                    throw new Exception("Unable to decode thumbnail. Error: ".  ldap_error($this->ldap),  self::ERROR_IMG_DECODE);
    203                 }
    204                 //echo '<img src="'.$this->data_uri($info[0], 'image/png').'">';
    205             }
    206             
    207             
    208             if(!$raw){
    209                 return $this->data_uri($info[0], 'image/png');
    210             }
    211             else{
    212                 return $info[0];
    213             }
    214         }
    215         else {
    216             // invalid name or password
    217             $this->status='Cant authenticate for search on LDAP';
    218             throw new Exception($this->status.' '.  ldap_error($this->ldap), self::ERROR_CANT_AUTH);
    219         }
    220         ldap_unbind($this->ldap);
    221     }
    222     
    223     /**
    224      * Tries to authenticate suplied user with suplied pass
    225      * @param type $user
    226      * @param type $password
    227      * @return boolean
    228      * @throws Exception
    229      */
    230     public function authenticate($user=null, $password=null) {
    231        $this->refreshCredentials($user, $password);
    232         //since conection is one off we need to get it
    233         $this->init_connection();
    234         
    235         // verify user and password
    236         $bind = @ldap_bind($this->ldap, $user . $this->ldap_usr_dom, $password);
    237 
    238         
    239         if($bind) {
    240             // valid
    241             // check presence in groups
    242             $filter = "(sAMAccountName=" . $user . ")";
    243             $attr = array("memberof");
    244             $result = @ldap_search($this->ldap, $this->ldap_dn, $filter, $attr);
    245             if($result==FALSE){
    246                  throw new Exception("Unable to search LDAP server. Reason: ".  ldap_error($this->ldap),  self::ERROR_CANT_SEARCH);
    247             }  
    248             $entries = ldap_get_entries($this->ldap, $result);
    249             
    250             //save result for future use
    251             $this->result=$entries;
    252 
    253             
    254             
    255             $access = 0;
    256             
    257             // check groups
    258             foreach($entries[0]['memberof'] as $grps) {
    259                 // is manager, break loop
    260                 if (strpos($grps, $this->ldap_manager_group)) { $access = 2; break; }
    261 
    262                 // is user
    263                 if (strpos($grps, $this->ldap_user_group)) $access = 1;
    264             }
    265 
    266             if ($access != 0) {
    267                 // establish result vars
    268                 
    269                 $this->status='Authenticated';
    270                 $this->access=$access;
    271                 $this->user= $user;
    272                 $this->auth=1;
    273                 return true;
    274             } else {
    275                 // user has no rights
    276                 $this->access=$access;
    277                 $this->user= $user;
    278                 $this->auth=1;
    279                 $this->status='User exists but not part of the target group';
    280                 throw new Exception($this->status.' '.  ldap_error($this->ldap),  self::ERROR_WRONG_USER_GROUP);
    281             }
    282 
    283         } else {
    284             // invalid name or password
    285             $this->status='Cant authenticate for search on LDAP';
    286             throw new Exception($this->status.' '.  ldap_error($this->ldap),  self::ERROR_CANT_AUTH);
    287         }
    288         ldap_unbind($this->ldap);
    289     }
    290     
    291     /**
    292      * Saves new credentials if we got new or sets the old ones into referenced vars
    293      * @param type $user Reference to var that shuld contain username or null
    294      * @param type $password Reference to var that shuld contain password or null
    295      */
    296     private function refreshCredentials(&$user,&$password) {
    297         $newCredentials=TRUE;
    298         //since we cant set those in param def
    299         if($password===null){$password=  $this->password;$newCredentials=FALSE;}
    300         if($user===null){$user=  $this->user;$newCredentials=FALSE;}
    301         //store user pass and name for future use
    302         if($newCredentials){$this->userInit($user, $password);}
    303     }
    304 
    305 }
  • 相关阅读:
    [WC2010]重建计划
    [POJ1741]Tree
    [NOI2008]志愿者招募
    [BZOJ2127]happiness
    「网络流 24 题」太空飞行计划
    [TJOI2015]线性代数
    [HDU2874]Connections between cities
    [POI2007]ZAP-Queries
    [SCOI2010]幸运数字
    POJ 2826 An Easy Problem?!
  • 原文地址:https://www.cnblogs.com/zhangchenliang/p/3935560.html
Copyright © 2020-2023  润新知