Perl Dancer2 Аутентификация Управление паролями

Таким образом, любой, кто использовал perl dancer, знает, что для аутентификации пользователя при входе в систему вы можете вызвать authentication_user

authenticate_user(
    params->{username}, params->{password}
);

Это часть плагина Auth::Extensible.

Мне кажется, что это поощряет использование хранения паролей в виде простого текста! Конечно, вы можете сначала хешировать пароль, а затем убедиться, что сохраненный пароль является тем же хэшем, но это, похоже, скорее обходной путь, и я обнаружил, что это не гарантирует работу. У меня это работает только с использованием sha1, который не следует использовать. Я хочу использовать Bcrypt, но парольная фраза просто не совпадает. Возможно, нечетные символы не совпадают, я не уверен.

Дело в том, что с помощью плагина dancer Passphrase я уже могу проверить имя пользователя и пароль, даже не полагаясь на authentication_user для их проверки. Но для того, чтобы фреймворк dancer рассмотрел пользователя, вошедшего в систему, вам все равно нужно вызвать authentication_user, которому должен быть передан пароль.

Я полностью застрял. Мне любопытно, как другим людям удалось использовать правильное управление паролями в dancer2?


person jeffez    schedule 30.08.2017    source источник
comment
Не похоже, что вы даже просмотрели Dancer2::Plugin:: Документация Auth::Extensible.   -  person Sinan Ünür    schedule 30.08.2017
comment
Я размещаю сообщения в подобных местах только в крайнем случае после прочтения всей документации, которую могу найти. Если вы собираетесь просто дать типичный ответ типа rtfm, по крайней мере, подкрепите его некоторыми рассуждениями, иначе это не похоже на то, что вы даже просмотрели вопрос.   -  person jeffez    schedule 30.08.2017
comment
С чего вы взяли, что пароль нужно хранить в виде обычного текста? Код, который вы показали, принимает учетные данные, предоставленные пользователем. Очевидно, что это обычный текст, но он нигде не хранится, а просто получен по сети. authenticate_user позаботится о хешировании и сравнении под капотом. Как он это делает, совершенно прозрачно. Он поставляется с кучей разных провайдеров, но вы также можете свернуть свой собственный, если вам нужно что-то еще.   -  person simbabque    schedule 30.08.2017
comment
Чтобы уточнить, я использую провайдера: «База данных», поэтому у меня есть БД с таблицей пользователей. Причина, по которой я говорю, что это поощряет хранение паролей в виде простого текста, заключается в том, что authentication_user не будет аутентифицироваться, если params-›{password} точно не совпадает с тем, что находится в базе данных. Это не хэш это. Однако - user_password username => 'jbloggs', new_password => 'secret' будет хэшировать его в sha512 перед сохранением.   -  person jeffez    schedule 31.08.2017


Ответы (2)


Во-первых, я повторяю комментарии "вам почти наверняка не нужно использовать authenticate_user()". Плагин может справиться со всем этим за вас.

Однако «это не хеширует» неправильно; вот как это работает. Ключевое слово authenticate_user перебирает все настроенные области аутентификации и для каждой из них запрашивает метод authenticate_user() этого провайдера, чтобы узнать, принимает ли он имя пользователя и пароль. Поставщик Database (и другие) извлекает запись из БД и использует $self->match_password() (который поступает из роль поставщика), чтобы проверить ее; этот код проверяет, начинается ли сохраненный пароль из базы данных с {scheme}, и если да, использует Crypt::SaltedHash->validate для проверки того, что введенный пользователем пароль (в виде обычного текста, так как он только что пришел по сети) соответствует сохраненному хешированному паролю ($correct в приведенный ниже код является сохраненным паролем):

if ( $correct =~ /^{.+}/ ) {

    # Looks like a crypted password starting with the scheme, so try to
    # validate it with Crypt::SaltedHash:
    return Crypt::SaltedHash->validate( $correct, $given );
}

Итак, да, если ваш сохраненный пароль в базе данных хеширован, то он будет соответствовать ему, если указанный пароль соответствует этому хешу.

Для примера того, как должен выглядеть сохраненный хешированный пароль, вот вывод прилагаемой утилиты generate-crypted-password:

[davidp@supernova:~]$ generate-crypted-password 
Enter plain-text password ?> hunter2
Result: {SSHA}z9llSLkkAXENw8FerEchzRxABeuJ6OPs

Подробнее о том, какие алгоритмы он поддерживает, см. в документе Crypt::SaltedHash. формат, который он использует (который «происходит из RFC-3112 и расширяется за счет использования различных цифровых алгоритмов»).

Имейте в виду, что код, стоящий за authenticate_user, — это именно то, что используется для вас под капотом.

В качестве примера, позволяющего плагину делать всю работу за вас, рассмотрим:

get '/secret' => require_login sub {
    my $user = logged_in_user();
    return "Hi, $user->{username}, let me tell you a secret";
};

... это оно. require_login означает, что плагин проверит, вошел ли пользователь в систему, и если нет, перенаправит его на страницу входа для входа. Вам не нужно вызывать authenticate_user самостоятельно, вам не нужно устанавливать какие-либо переменные сеанса или что-либо. logged_in_user() вернет хэш-ссылку информации о вошедшем в систему пользователе (а поскольку в коде маршрута есть require_login, в этот момент он гарантированно будет, поэтому вам не нужно проверять).

Если вам нужно проверить, что у них есть подходящая роль, а не только то, что они вошли в систему, посмотрите вместо этого require_role в документации.

person David Precious    schedule 12.10.2017

В документации для Dancer2::Plugin::Auth::Extensible, описание для authenticate_user() гласит:

Обычно вы хотите, чтобы встроенный код обработки входа имел дело с аутентификацией пользователей, но в случае, если вам нужно сделать это самостоятельно, это ключевое слово принимает имя пользователя и пароль ...

Что на мой взгляд подразумевает, что вам вообще не следует вызывать эту функцию, если только вы не делаете что-то особенно умное.

Я сам не использовал этот модуль, но мне кажется, что все хеширование и шифрование должны обрабатываться одним из поставщики аутентификации, и если нет ни одного, подходящего для используемого вами случая, вы можете напишите сами.

Всякий раз, когда мне нужно сохранить безопасные пароли для приложения Dancer, я использую Dancer2::Plugin: :Пароль. Интересно, стоит ли мне подумать о написании для него поставщика аутентификации в стиле Auth::Extensible.

person Dave Cross    schedule 30.08.2017
comment
Правильный материал шифрования должен обрабатываться поставщиком аутентификации. В документации для Auth::Extensible::Provider::Database указано, что используется Crypt::SaltedHash. Однако authentication_user по-прежнему соответствует только текстовому паролю в базе данных. В итоге я использовал Dancer2::Plugin::Passphrase для самостоятельной аутентификации, но я уверен, что то, что я пытаюсь сделать, не является чем-то особенным, требующим такого уровня работы. - person jeffez; 31.08.2017
comment
@jeffez: Но почему ты звонишь authenticate_user()? Для большинства применений это не нужно. - person Dave Cross; 31.08.2017
comment
Я так понимаю, что authentication_user() используется для проверки имени пользователя и пароля перед добавлением переменных сеанса, регистрирующих пользователя. Это было все, что мне было нужно, но пароли будут совпадать только с обычным текстом, чего не должно происходить по умолчанию в документах Auth::Extensible::Provider::Database. В итоге я написал свое собственное сопоставление имени пользователя и пароля, но это как бы противоречит «соглашению о конфигурации». - person jeffez; 04.09.2017
comment
Насколько я понимаю, authentication_user() используется для проверки имени пользователя и пароля перед добавлением переменных сеанса, регистрирующих пользователя. Тогда я могу только предложить вам более внимательно изучить документацию. При обычном использовании все это делается за вас, и вам не нужно вызывать authenticate_user() самостоятельно. - person Dave Cross; 04.09.2017