Saturday, November 25, 2006

Xác thực LDAP cho ứng dụng web PHP

Mỗi khi triển khai một ứng dụng mới trong công ty, người dùng lại "rên" lên vì phải nhớ (lưu vào máy) thêm một password nữa. Triển khai một giải pháp Single Sign On (SSO) là hoàn toàn không đơn giản cả về chi phí lẫn kỹ thuật. Một giải pháp Single Password là khả thi và chấp nhận được. Thông tin cơ bản về user và password được lưu trên LDAP, các ứng dụng khác có thể truy cập database này cho mục đích xác thực (authentication), đồng thời cũng có thể import các thông tin cơ bản từ LDAP để tạo database user riêng cho mục đích phân quyền trên ứng dụng.

Các ứng dụng web dựa trên PHP cho doanh nghiệp ngày càng phổ biến: CRM, groupware, project management, ticket system, online training,... Hầu hết có hỗ trợ xác thực LDAP sẵn, tuy nhiên cũng có một số ứng dụng chưa có. Nhưng đó không phải là trở ngại lớn, chỉ với một đoạn mã đơn giản chèn vào trước phần xác thực của ứng dụng ta có thể duy trì mục tiêu single pasword cho người dùng. Đoạn mã này trích từ ASPN PHP Cookbook:
$ldapconfig['host'] = 'localhost';
$ldapconfig['port'] = NULL;
$ldapconfig['basedn'] = 'dc=localhost,dc=com';
$ldapconfig['authrealm'] = 'My Realm';

function ldap_authenticate() {
global $ldapconfig;
global $PHP_AUTH_USER;
global $PHP_AUTH_PW;

if ($PHP_AUTH_USER != "" && $PHP_AUTH_PW != "") {
$ds=@ldap_connect($ldapconfig['host'],$ldapconfig['port']);
$r = @ldap_search( $ds, $ldapconfig['basedn'], 'uid=' . $PHP_AUTH_USER);
if ($r) {
$result = @ldap_get_entries( $ds, $r);
if ($result[0]) {
if (@ldap_bind( $ds, $result[0]['dn'], $PHP_AUTH_PW) ) {
return $result[0];
}
}
}
}
header('WWW-Authenticate: Basic realm="'.$ldapconfig['authrealm'].'"');
header('HTTP/1.0 401 Unauthorized');
return NULL;
}

if (($result = ldap_authenticate()) == NULL) {
echo('Authorization Failed');
exit(0);
}
echo('Authorization success');
print_r($result);
?>

Đơn giản là dùng ldap_bind với username/password của người dùng, nếu OK là xác thực thành công. Cũng nên lưu ý là ldap_bind đơn giản không mã hóa thông tin, nếu muốn an toàn hơn thì dùng LDAP+SSL hoặc LDAPS.

No comments: