2011-12-15 112 views
0

我想建立一個簡單的基於Web的目錄導航/管理應用程序。永久ldap認證會話

報名要求:

  • 的Active Directory(或其他目錄服務)域用戶接入 這個web應用,並且具有相同的域用戶名/密碼 憑據登錄。
  • 然後用戶可以瀏覽目錄樹,創建/編輯條目, 編輯條目的屬性,等等。

我用perl的Net :: LDAP爲LDAP操作,如:

#!/usr/bin/perl -wT 

use Net::LDAP; 
use CGI qw(:standard); 
use CGI::Carp qw(warningsToBrowser fatalsToBrowser); 

my $ssl = 1; 
my $srv = '192.168.56.110'; 
my $uri = $ssl ? 'ldaps://' : 'ldap://'; 

my $c = Net::LDAP->new($uri . $srv) or 
    die "Unable to connect to server: [email protected]\n"; 

# !!! This is a temporary workaround !!! 
my $binddn = "cn=Administrator,cn=users,dc=example,dc=com"; 
my $passwd = "password"; 

my $mesg = $c->bind($binddn, password => $passwd); 
die 'Unable to bind: ' . $mesg->error . "\n" if $mesg->code; 

# DN to be deleted 
my $dn = param('DN'); 

$mesg = $c->delete($dn); 
die 'Error in delete: '. $mesg->error() ."\n" if $mesg->code(); 

$c->unbind; 

我可以調用這個CGI腳本以HTML形式,如:

<form action="/cgi-bin/del.cgi" method="post"> 
<br>Peter Parker 
<input type="radio" name="DN" 
    value="cn=peter parker,cn=users,dc=example,dc=com"> 
<br>Clark Kent 
<input type="radio" name="DN" 
    value="cn=clark kent,cn=users,dc=example,dc=com"> 
<br> 
<input type="submit" value="Delete User"> 
</form> 

這段代碼的問題是,LDAP操作使用ADMI而不是運行Web應用程序的用戶憑據。我正在使用這種解決方法,因爲我無法每次都向用戶詢問他/她的憑據......而且我不知道如何讓用戶永久驗證身份。

我的web應用程序認證通過LDAP用戶,詢問他的憑據,併發出綁定請求到目錄服務,如:

... 
# read user supplied credentials 
my $user_id = param('user_id'); 
my $password = param('password'); 

# now find the DN of user_id in directory 
my $ssl = 1; 
my $srv = '192.168.56.110'; 
my $uri = $ssl ? 'ldaps://' : 'ldap://'; 

my $c = Net::LDAP->new($uri . $srv) or 
    die "Unable to connect to server: [email protected]"; 

# admin credentials are needed here to find the user DN 
my $rootdn = "cn=Administrator,cn=users,dc=example,dc=com"; 
my $rootpw = "secret"; 

my $mesg = $c->bind($rootdn, password => $rootpw); 
die "Unable to bind: ". $mesg->error if $mesg->code; 

$mesg = $c->search(
    base => 'dc=example,dc=com', 
    scope => 'sub', 
    filter => "(&(objectClass=user)(sAMAccountName=$user_id))", 
    attrs => ['sAMAccountName'], 
); 
die "Bad search: ". $mesg->error() if $mesg->code(); 

my ($entry) = $mesg->entries; 
die "User not found: $user_id\n" unless $entry; 

my $dn = $entry->dn; 

# User DN found.. now check the credentials 
$mesg = $c->bind($dn, password => $password); 
die "Unable to bind: ". $mesg->error if $mesg->code; 

$c->unbind(); 

# credentials validated! 
print header, start_html('Welcome!'), h1('Hello, YOU!'), end_html; 

之後,一個cookie被髮送到用戶的瀏覽器發起網絡會話。 我可以將用戶憑據保存在數據庫中,然後在需要時將其傳遞給del.cgi(以及其他類似的腳本)..但我認爲這不是很好的安全措施。

只要Web會話處於活動狀態,我可以做些什麼來保持永久的LDAP認證會話?

回答

0

沒有會話。當LDAP客戶端連接到目錄服務器時,連接未經身份驗證。如果綁定請求成功,則建立連接的授權狀態。連接保持在該授權狀態,直到下一個綁定請求,客戶端斷開連接或服務器斷開連接。根據本地設置,可能會保持連接無限期地保持活動或類似狀態。或者客戶端可以定期發送另一個綁定請求。現代的,專業品質的目錄服務器支持斷開閒置的客戶端,或者在一段時間過去之後斷開客戶端連接,或者在一定數量的LDAP操作已經傳輸之後。請注意,網絡管理員可能因其自身原因而不允許永久連接。

  • LDAP客戶端應在LDAP請求後檢查響應控制。未能檢查響應控件將導致客戶端缺少來自服務器的重要信息。
  • LDAP客戶端必須知道服務器可以以擴展結果的形式發送未經請求的通知。未能處理未經請求的通知可能導致表現不佳的LDAP客戶端。大多數通知都是斷開連接通知,意味着服務器無論出於何種原因都會斷開客戶端。

請參閱"LDAP: programming Practices"瞭解更多信息。

出於好奇,爲什麼要編碼這樣的東西? Apache Directory Studio是一款出色的LDAP客戶端。