Я создал расширение AuthPlugin для аутентификации по одноразовому паролю SecurID. Все идет нормально. Я могу аутентифицировать и создавать пользователей при первом входе в систему. Однако при первом входе в систему всегда выполняется проверка подлинности дважды. Он аутентифицирует первый раз для создания пользователя и второй раз для фактического входа в него. Вы можете увидеть проблему здесь: одноразовый пароль используется в первый раз, поэтому пользователь не вошел в систему. Последующие входы в систему работают нормально ,
Я проследил первые аутентификационные звонки /includes/specials/SpecialUserlogin.php
(и я не уверен, какой из них вызывается, но я мог бы найти обидчика и удалить его):
<?php
/**
* Make a new user account using the loaded data.
* @private
* @throws PermissionsError|ReadOnlyError
* @return Status
*/
public function addNewAccountInternal() {
// ...snip...
// If we are not allowing users to login locally, we should be checking
// to see if the user is actually able to authenticate to the authenti-
// cation server before they create an account (otherwise, they can
// create a local account and login as any domain user). We only need
// to check this for domains that aren't local.
if ( 'local' != $this->mDomain && $this->mDomain != '' ) {
if (
!$wgAuth->canCreateAccounts() &&
(
!$wgAuth->userExists( $this->mUsername ) ||
!$wgAuth->authenticate( $this->mUsername, $this->mPassword )
)
) {
return Status::newFatal( 'wrongpassword' );
}
}
//...snip...
/**
* Attempt to automatically create a user on login. Only succeeds if there
* is an external authentication method which allows it.
*
* @param $user User
*
* @return integer Status code
*/
function attemptAutoCreate( $user ) {
// ...snip...
if ( !$wgAuth->authenticate( $user->getName(), $this->mPassword ) ) {
wfDebug( __METHOD__ . ": \$wgAuth->authenticate() returned false, aborting\n" );
return self::WRONG_PLUGIN_PASS;
}
Итак, если всем пользователям необходимо пройти проверку подлинности с помощью системы одноразовых паролей (если я запрещаю входы в систему с локальных учетных записей и создание локальной учетной записи), возникает ли проблема при удалении нарушителя authenticate
звонки? Я здесь ужасно неуверен? Или есть лучший способ сделать это? Должен ли я делать что-то кроме расширения AuthPlugin
? Например, я переопределяю эти AuthPlugin
методы:
<?php
/**
* Return true to prevent logins that don't authenticate here from being
* checked against the local database's password fields.
*
* This is just a question, and shouldn't perform any actions.
*
* @return bool
*/
public function strict() {
return true;
}
/**
* Check if a user should authenticate locally if the global authentication fails.
* If either this or strict() returns true, local authentication is not used.
*
* @param string $username Username.
* @return bool
*/
public function strictUserAuth( $username ) {
return true;
}
Я хотел бы избежать предварительного создания всех пользователей и их синхронизации, но это был бы один из способов избежать первоначальных дублирующих вызовов аутентификации.
Кстати, я думаю, что настоящий вызов аутентификации для сеанса происходит в includes/User.php
:
<?php
public function checkPassword( $password ) {
global $wgAuth, $wgLegacyEncoding;
$this->load();
// Certain authentication plugins do NOT want to save
// domain passwords in a mysql database, so we should
// check this (in case $wgAuth->strict() is false).
if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
return true;
Я думаю, что лучший способ — это использовать так же, как TwoFactorAuthentication расширение, используемое на wikitech.wikimedia.org.
Вы можете использовать AbortLogin
Крюк, чтобы проверить свой одноразовый пароль, перед проверкой пользовательских данных. Проблема: необходимо убедиться, что одноразовый пароль помечается как «используемый» только после успешного входа пользователя.
(Я надеюсь, что вы не хотите заменять «обычный» пароль пользователя на «только» одноразовый пароль).
Других решений пока нет …