2009-09-09 6 views
6

Tôi đang làm việc trên dự án CakePHP và hiện đang xây dựng phần xác thực người dùng của nó. Vấn đề là thông tin xác thực của tôi (ví dụ: mật khẩu) không được lưu trữ trong cơ sở dữ liệu của tôi - nguồn xác thực là LDAP nhưng câu hỏi của tôi áp dụng như nhau đối với bất kỳ nguồn không phải cơ sở dữ liệu nào.Nguồn xác thực thay thế trong CakePHP (LDAP)

Dường như Bánh chỉ xử lý mật khẩu khi chúng tồn tại trong cơ sở dữ liệu cục bộ. The Cake Cookbook suggests mà bạn có thể cho nó biết một bộ điều khiển/mô hình/đối tượng khác để cung cấp quy trình ủy quyền bằng cách sử dụng biến số $this->Auth->authorize, tuy nhiên, xem mã (cụ thể là the Auth::startup() function) có vẻ như bánh sẽ luôn truy vấn cơ sở dữ liệu trước tiên. tên người dùng/mật khẩu phù hợp, trước khi xem xét đối tượng thay thế bạn chỉ định với Auth->authorize. Tức là, việc thay đổi authorize chỉ thêm bộ lọc cấp hai, nó không thay thế tra cứu cơ sở dữ liệu.

// The process 
1. User provides details 
2. Cake checks the database 
3. If OK, then check the custom object method 
4. If OK, return true 

// What I'd like: 
1. User provides details. 
2. Check the custom object method 
3. If OK, return true 
4. Profit. 

Bất kỳ ý tưởng nào về cách thực hiện điều này, hy vọng không có hack các tệp lõi?

+0

+1 cho lợi nhuận ... – Stephen

Trả lời

8

Giả sử bạn chỉ đơn giản là bắt buộc đối với LDAP và đang lưu trữ/lấy dữ liệu người dùng từ MySQL, phương pháp này sẽ làm việc như một "cầu nối" mà sẽ tự động tạo tài khoản cho lần đăng nhập thành công:

// app/controllers/components/ldap_auth.php 
<?php 
App::import('Component', 'Auth'); 
class LdapAuthComponent extends AuthComponent { 
/** 
* Don't hash passwords 
*/ 
    function hashPasswords($data){ 
     return $data; 
    } 
/** 
* We will initially identify the user 
*/ 
    function identify($user=null, $conditions=null) { 
     // bind credentials against ldap 
     $ldapUser = $this->_ldapAuth($user); // do your stuff 
     if (!$ldapUser) { 
      return null; // if bind fails, then return null (as stated in api) 
     } 
     // get the cake model you would normally be authenticating against 
     $model =& $this->getModel(); // default is User 
     // check for existing User in mysql 
     $user = $model->find('first', array('conditions' => array(
      'username' => $ldapUser['cn'] 
     )); 
     // if no existing User, create a new User 
     if (!$user) { 
      $user = $model->save(array('User' => array(
       'username' => $ldapUser['cn'], 
       // .. map needed ldap fields to mysql fields .. 
      ))); 
      if (!$user) { 
       $this->cakeError('ldapCreateUser'); 
      } 
      // pass the id of the newly created User to Auth's identify 
      return parent::identify($model->id, $conditions); 
     } 
     // pass the id of the existing User to Auth's identify 
     return parent::identify($user[$this->userModel][$model->primaryKey], $conditions); 
    } 
/** 
* Lets check LDAP 
* 
* @return mixed Array of user data from ldap, or false if bind fails 
*/ 
    function _ldapAuth($user) { 
     $username = $user[$this->userModel][$this->fields['username']]; 
     $password = $user[$this->userModel][$this->fields['password']]; 
     // use the php ldap functions here 
     return $ldapUser; 
    } 
} 
?> 

để sử dụng, thay thế tất cả các tham chiếu tới Auth với LdapAuth trong ứng dụng của bạn hoặc làm theo các instructions here.

Lưu ý rằng mặc dù được bảo vệ _ldapAuth() phương pháp thể được trừu tượng ra một mô hình LdapUser, và rằng mô hình nên đọc từ một LdapSource, và máy chủ LDAP cài đặt kết nối nên được trong database.php config, và LdapAuthComponentnên được điều chỉnh để sử dụng ánh xạ trường có thể định cấu hình, đây không phải là yêu cầu để "hoàn thành công việc". :)

1

Auth::authorize thực sự không phải là sự thay thế cho dữ liệu mô hình, nó chỉ thêm vào đó.

5.2.6.10 authorize

Thông thường, AuthComponent sẽ cố gắng xác minh rằng các thông tin đăng nhập bạn đã nhập không chính xác bằng cách so sánh chúng với những gì đang được lưu trữ trong mô hình người dùng của bạn. Tuy nhiên, có những lúc bạn có thể muốn làm một số công việc bổ sung trong việc xác định thông tin xác thực phù hợp.

Đó không phải là vấn đề, vì các chi tiết LDAP phải được trừu tượng hóa trong mô hình. Bánh vẫn sẽ kiểm tra mô hình cho tên người dùng và mật khẩu, nhưng nó là nhận được câu trả lời của nó một cách minh bạch từ một thư mục LDAP. Bạn chỉ cần triển khai LDAP datasource cho mô hình. Có thể những số này twoarticles có thể giúp bạn bắt đầu.

0

Tôi đã có thể hack xung quanh cách Bánh thực hiện một cách tương đối tinh ranh, nhưng có thể chấp nhận được.

Tôi đã thêm trường "mật khẩu" vào bảng người dùng của mình và đặt mật khẩu của mọi người thành "a" (mặc dù bạn có thể sử dụng bất kỳ thứ gì).

Sau đó, tôi đã thêm một hàm băm tùy vào mô hình của tôi:

function hashPasswords($data) { 
    $data['User']['password'] = 'a'; 
    return $data; 
} 

Và nói với bộ điều khiển của tôi để sử dụng mô hình đó cho băm:

$this->Auth->authenticate = ClassRegistry::init('User'); 

này bây giờ có nghĩa là bước đầu tiên của bánh mà sẽ luôn luôn vượt qua (giả sử tên người dùng tồn tại trong bảng). Chức năng authorize giờ đây có thể thực hiện điều đó và thực hiện kiểm tra thích hợp bằng bất kỳ phương thức nào bạn muốn.

Đó là cơ bản thay đổi quá trình này như sau:

// The process 
1. User provides details 
2. Cake checks the database **and always returns OK** 
3. If OK, then check the custom object method 
4. If OK, return true