0

我创建了一个 AuthPlugin 扩展来执行 SecurID 一次性密码身份验证。到目前为止,一切都很好。我可以在第一次登录时验证并创建用户。但是,第一次登录总是验证两次。它第一次验证以创建用户,第二次验证以实际登录。您可能会在这里看到问题:第一次使用一次性密码,因此用户未登录。后续登录工作正常.

我已经追踪了第一个 auth 调用/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;
4

1 回答 1

1

我认为最好的方法是使用与 wikitech.wikimedia.org 上使用的TwoFactorAuthentication扩展相同的方法。

在检查用户数据之前,您可以使用AbortLoginHook 检查您的一次性密码。问题:当用户成功登录时,您必须确保一次性密码仅被标记为“已使用”。

(我希望您不想用“仅”一次密码替换“普通”用户密码)。

于 2014-10-27T09:53:34.877 回答