永久 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: $@\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;
我可以使用 HTML 表单调用此 cgi 脚本,如下所示:
<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 操作是使用管理凭据,而不是运行 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: $@";
# 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 发送到启动 Web 会话的用户浏览器。 我可以将用户凭据保存在数据库中,然后在需要时随时将其传递给 del.cgi (和其他类似的脚本)..但我认为这不是良好的安全实践。
只要网络会话处于活动状态,我该怎么做才能保持永久的 LDAP 身份验证会话?
I am trying to build a simple web based directory navigation/administration application.
Application requirements:
- An Active Directory (or another directory service) domain user access
this web application and log in with the same domain user/password
credentials. - Then the user can navigate the directory tree, create/edit entries,
edit an entry's attribute, etc..
I'm using perl Net::LDAP for the ldap operations, as in:
#!/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: $@\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;
I can call this cgi script with a HTML form, as in:
<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>
The problem with this code is that the ldap operations are using administrative credentials, not the credentials of the user running the web application. I'm using this workaround because I can't ask the user for his/her credentials every time.. and I don't know how to keep a user permanently authenticated.
My web application authenticate the user via ldap, asking he's credentials and issuing a bind request to the directory service, as in:
...
# 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: $@";
# 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;
After that, a cookie is sent to the user browser initiating a web session.
I could keep the user credentials in a database and then pass it to del.cgi (and other similar script) any time I needed.. but I don't think it's good security practice.
What can I do to keep a permanent ldap authenticated session as long as the web session is active?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有会议。当 LDAP 客户端连接到目录服务器时,该连接未经身份验证。绑定请求如果成功,就会建立连接的授权状态。连接将保持该授权状态,直到下一个绑定请求、客户端断开连接或服务器断开连接。根据本地设置,可以通过保持活动或类似的方式无限期地保持连接打开。或者客户端可以周期性地发送另一个绑定请求。现代、专业品质的目录服务器支持断开空闲客户端的连接,或者在经过一定时间后或在传输了一定数量的 LDAP 操作后断开客户端的连接。请注意,网络管理员可能会出于自己的原因禁止永久连接。
请参阅“LDAP:编程实践”了解更多信息信息。
出于好奇,为什么要编写这样的代码? Apache Directory Studio 是一个优秀的 LDAP 客户端。
There is no session. When an LDAP client connects to the directory server, the connection is unauthenticated. The bind request, should it be successful, establishes the authorization state of the connection. The connection remains in that authorization state until the next bind request, client disconnect, or server disconnect. Depending on the local setup, it may be possible to keep the connection open indefinitely with keep-alives or something similar. or the client can transmit another bind request periodically. Modern, professional-quality directory servers support disconnecting idle clients, or disconnecting clients after a certain period of time has passed, or after a set number of LDAP operations have been transmitted. Note that network administrators may disallow permanent connections for reasons of their own.
Please see "LDAP: programming Practices" for more information.
Out of curiosity, why code such a thing? Apache Directory Studio is an excellent LDAP client.