Эквивалент "su" для аутентификации веб-приложений, вопрос дизайна - PullRequest
4 голосов
/ 27 февраля 2011

Я разрабатываю и поддерживаю портал для клиентов, написанный на Perl / Catalyst. Мы используем подключаемые модули проверки подлинности Catalyst (с внутренним хранилищем LDAP в сочетании с несколькими правилами deny_unless, чтобы гарантировать, что нужные люди имеют правильное членство в группе).

Часто при управлении разрешениями клиента нам необходимо проверить настройки пользователя, прежде чем мы передадим что-то. В настоящее время наш единственный выход - сбросить пароль пользователя и войти в него самостоятельно, но это далеко не идеально, особенно если пользователь уже установил свои собственные пароли и т. Д.

Мой вопрос таков: для Catalyst кто-нибудь сталкивался с методом олицетворения учетной записи пользователя, так что при наличии правильных привилегий супер-администратора можно временно выдать себя за другую учетную запись при тестировании параметра, а затем отменить один раз сделано?

Если не в Catalyst, то как люди подошли к этому в других средах или в своих собственных пользовательских решениях? Следует признать, что это представляет собой потенциально вопиющий вектор атаки для веб-приложения, но если люди вынуждены внедрять, как люди подошли к дизайну для этого? Возможно, какое-то серьезное печенье-сессия-фу? Или, возможно, система фактического / эффективного идентификатора?

1 Ответ

5 голосов
/ 28 февраля 2011

Мы используем пользовательский контроллер аутентификатора, пользовательский класс пользователя (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, но оборачиваем его вокруг нашего пользовательского пользовательского класса для большего контроля.Возможно, я мог бы создать специальную область для суррогата, но вместо этого я выбрал собственный класс пользователя.Это было сделано некоторое время назад, и я могу вспомнить, почему мы так поступили.

...