0

SecurID ワンタイム パスワード認証を行うための AuthPlugin 拡張機能を作成しました。ここまでは順調ですね。最初のログイン時にユーザーを認証して作成できます。ただし、最初のログインは常に 2 回認証されます。最初に認証してユーザーを作成し、2 回目に実際にログインします。ここで問題が発生する可能性があります。初回はワンタイム パスワードが使用されるため、ユーザーはログインされません。その後のログインは正常に機能します。 .

最初の認証呼び出しを追跡しました/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;
}

すべてのユーザーを事前に作成して同期を維持することは避けたいのですが、それは最初の重複した認証呼び出しを回避する 1 つの方法です。

ところで、セッションの実際の認証呼び出しは次の場所で行われると思います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拡張機能と同じ方法を使用するのが最善の方法だと思います。

AbortLoginユーザーデータがチェックされる前に、フックを使用してワンタイムパスワードをチェックできます。問題: ユーザーが正常にログインしたときにのみ、ワンタイム パスワードが「使用済み」としてマークされていることを確認する必要があります。

(「通常の」ユーザーパスワードを「のみ」のワンタイムパスワードに置き換えたくないことを願っています)。

于 2014-10-27T09:53:34.877 に答える