2011-12-15 113 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客户端。