我开发并维护一个用Perl / Catalyst编写的客户门户。我们使用Catalyst身份验证插件(带有LDAP存储后端,再加上一些deny_unless规则,以确保合适的人拥有正确的组成员资格)。
通常,在管理客户的权限时,我们需要在交出之前测试用户的设置。目前,我们唯一的办法是重置用户的密码并自行登录,但这并不理想,特别是如果用户已经设置了自己的密码等。
我的问题是:对于Catalyst,有没有人遇到冒充用户帐户的方法,以便在给定正确的超级管理员权限的情况下,可以在测试设置时临时模拟其他帐户,然后退出一次做什么?
如果不在Catalyst中,那么人们如何在其他框架或自己的自定义解决方案中接近这个?不可否认,这是为Web应用程序引入可能极为恶劣的攻击向量的东西,但如果被迫实施,那么人们如何为此设计?也许是一些严肃的cookie-session-fu?或者可能是一个actualID / effectiveID系统?
答案 0 :(得分:5)
我们使用自定义身份验证控制器,自定义用户类(MyApp :: Core :: User)和几个领域:
package MyApp::Controller::Auth;
...
sub surrogate : Local {
my ( $self, $c ) = @_;
my $p = $c->req->params;
my $actual_user = $c->user; # save it for later
try {
$c->authenticate({ id=>$p->{surrogate_id} }, 'none');
$c->session->{user} = new MyApp::Core::User(
active_user => $actual_user,
effective_user => $c->user );
$c->stash->{json} = { success => \1, msg => "Login Ok" };
} catch {
$c->stash->{json} = { success => \0, msg => "Invalid User" };
};
$c->forward('View::JSON');
}
在myapp.conf
中,我使用类似这样的内容:
<authentication>
default_realm ldap
<realms>
<ldap>
# ldap realm config stuff here
</local>
<none>
<credential>
class Password
password_field password
password_type none
</credential>
<store>
class Null
</store>
</none>
</realms>
</authentication>
这样我们就可以创建一个普通的Catalyst用户对象,但是将它包装在我们的自定义用户类中以获得更多控制权。我可能已经为代理创建了一个专门的领域,但我选择使用我自己的用户类。一段时间后我就完成了,我可以回想起为什么我们这样做了。