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 '
'; 
133         print_r($this->result,FALSE); 
134         echo '

';
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 }

 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/11607.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论