在MediaWiki中使用自定义PrimaryAuthenticationProvider登录时,“不允许自动创建帐户”

我正在使用MediaWiki编写自定义的PrimaryAuthenticationProvider,以针对我的API(而不是MediaWiki数据库)进行授权。但是,当我通过以下方式关闭LocalSettings.php中的自动创建功能时:

$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['read'] = false;

当我尝试使用正确的凭据登录我的API时,请求失败,并显示错误:Auto-creation of a local account failed: Automatic account creation is not allowed.

我想我没有对应该返回MediaWiki不应该创建用户的正确值的函数之一进行存根处理,但是我找不到哪个函数。当我启用$wgGroupPermissions['*']['createaccount'] = false;时,它开始工作,但是我想完全禁止创建帐户。我该如何实现?

这是我的身份验证提供程序的核心:

<?php
/**
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License,or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or fitness FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not,write to the Free Software Foundation,Inc.,* 51 Franklin Street,Fifth Floor,Boston,MA 02110-1301,USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 * @ingroup Auth
 */

use \MediaWiki\Auth\AuthenticationRequest;
use \MediaWiki\Auth\ButtonAuthenticationRequest;
use \MediaWiki\Auth\AbstractPrimaryAuthenticationProvider;
use \MediaWiki\Auth\AbstractPasswordPrimaryAuthenticationProvider;
use \MediaWiki\Auth\AuthManager;
use \MediaWiki\Auth\AuthenticationResponse;

/**
 * A primary authentication provider that uses the password field in the 'user' table.
 * @ingroup Auth
 * @since 1.27
 */
class MyAEGEEApiPrimaryAuthenticationProvider
    extends AbstractPasswordPrimaryAuthenticationProvider
{

    /**
     * @param array $params Settings
     *    the local password will be invalidated when authentication is changed
     *    and new users will not have a valid local password set.
     */
    public function __construct( $params = [] ) {
        parent::__construct( $params );
        $this->baseHost = 'https://my.aegee.eu';
        $this->loginUrl = $this->baseHost.'/services/oms-core-elixir/api/login';
        $this->getUserUrl = $this->baseHost.'/services/oms-core-elixir/api/members/me';
    }

    /**
     * Check if the password has expired and needs a reset
     *
     * @param string $username
     * @param \stdClass $row A row from the user table
     * @return \stdClass|null
     */
    protected function getPasswordResetData( $username,$row ) {
        return null;
    }

    /**
     * Makes a /login request to core.
     * @param{string} $username
     * @param{string} $password
     * @return $access_token
     */
    private function tryLogin($username,$password) {
        $ch = curl_init($this->loginUrl);

        $body = json_encode(array(
            'username'=>$username,'password'=>$password
        ));

        curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
        curl_setopt($ch,CURLOPT_POSTFIELDS,$body);
        curl_setopt($ch,CURLOPT_POST,CURLOPT_HTTPHEADER,array(
            'accept: application/json','Content-Type: application/json'
        ));

        $response = curl_exec($ch);
        $error    = curl_error($ch);
        $errno    = curl_errno($ch);

        if (is_resource($ch)) {
            curl_close($ch);
        }

        if (0 !== $errno) {
            wfDebugLog( 'MyAEGEEApi','Auth request returned error,failing.' );
            return null;
        }

        $response_parsed = json_decode($response);
        if (!$response_parsed->success) {
            wfDebugLog( 'MyAEGEEApi','Auth request not successful,failing.' );
            return null;
        }

        return $response_parsed->access_token;
    }

    /**
     * Fetches user from core.
     * @param{string} $access_token
     * @return $user
     */
    private function tryGetUser($access_token) {
        $ch = curl_init($this->getUserUrl);

        $body = json_encode(array(
            'username'=>$username,'Content-Type: application/json','X-Auth-Token: '.$access_token
        ));

        $response = curl_exec($ch);
        $error    = curl_error($ch);
        $errno    = curl_errno($ch);

        if (is_resource($ch)) {
            curl_close($ch);
        }

        if (0 !== $errno) {
            wfDebugLog( 'MyAEGEEApi','User request returned error,'User request not successful,failing.' );
            return null;
        }

        return $response_parsed->data;
    }

    /**
     * All fun starts here.
     */
    public function beginPrimaryAuthentication( array $reqs ) {
        if ( !$reqs[0] ) {
            wfDebugLog( 'MyAEGEEApi','No req,failing' );
            return AuthenticationResponse::newabstain();
        }

        $username = $reqs[0]->username;
        $password = $reqs[0]->password;

        if ( $username === null || $password === null ) {
            wfDebugLog( 'MyAEGEEApi','Empty password or username,failing' );
            return AuthenticationResponse::newabstain();
        }

        $username = User::getcanonicalName( $username,'usable' );
        if ( $username === false ) {
            wfDebugLog( 'MyAEGEEApi','username not usable,failing' );
            return AuthenticationResponse::newabstain();
        }

        $access_token = $this->tryLogin($username,$password);
        wfDebugLog( 'MyAEGEEApi','Got access token');

        if (!$access_token) {
            wfDebugLog( 'MyAEGEEApi','access token failed,failing.');
            return AuthenticationResponse::newabstain();
        }

        wfDebugLog( 'MyAEGEEApi','Auth succeeded.');

        $user = $this->tryGetUser($access_token);
        if (!$user) {
            wfDebugLog( 'MyAEGEEApi','User failed,failing.');
            return AuthenticationResponse::newabstain();
        }

        $username = $user->first_name.' '.$user->last_name;
        wfDebugLog( 'MyAEGEEApi','User succeeded: '.$username);

        return AuthenticationResponse::newPass( $username );
    }

    public function testUserCanAuthenticate( $username ) {
        wfDebugLog( 'MyAEGEEApi','testUserCanAuthenticate start');
        return true;
    }

    public function testUserExists( $username,$flags = User::READ_NORMAL ) {
        wfDebugLog( 'MyAEGEEApi','testUserExists called');
        return false;
    }

    /**
     * A stub to just implement something.
     */
    public function providerAllowsAuthenticationDataChange(
        AuthenticationRequest $req,$checkData = true
    ) {
        wfDebugLog( 'MyAEGEEApi','providerAllowsAuthenticationDataChange called');
        return \StatusValue::newGood( 'ignored' );
    }

    /**
     * A stub to just implement something.
     */
    public function providerChangeAuthenticationData( AuthenticationRequest $req ) {
        wfDebugLog( 'MyAEGEEApi','providerChangeAuthenticationData start');
    }

    /**
     * A stub to just implement something.
     */
    public function accountCreationType() {
        wfDebugLog( 'MyAEGEEApi','accountCreationType called start');
        return self::TYPE_NONE;
    }

    /**
     * A stub to just implement something.
     */
    public function testForaccountCreation( $user,$creator,array $reqs ) {
        wfDebugLog( 'MyAEGEEApi','testForaccountCreation called');
    }

    /**
     * A stub to just implement something.
     */
    public function beginPrimaryaccountCreation( $user,'beginPrimaryaccountCreation called');
        return AuthenticationResponse::newabstain();
    }

    /**
     * A stub to just implement something.
     */
    public function finishaccountCreation( $user,AuthenticationResponse $res ) {
        wfDebugLog( 'MyAEGEEApi','finishaccountCreation called');
        return null;
    }
}

然后在调试控制台中获得以下日志:


    IP: 172.18.0.2
    Start request POST /index.php/Special:UserLogin
    HTTP HEADERS:
    HOST: localhost
    USER-AGENT: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:70.0) Gecko/20100101 Firefox/70.0
    CONTENT-LENGTH: 208
    accEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    accEPT-ENCODING: gzip,deflate
    accEPT-LANGUAGE: en-US,en;q=0.5
    CONTENT-TYPE: application/x-www-form-urlencoded
    COOKIE: __test=1; Webstorm-87597fa=870153af-a572-4e74-a5d9-c7709900917d; sails.sid=s%3ASAu438xerbZoNUyYmK9AIxJCEBE_KkV0.%2FEydN2aTQPEaxd%2BhxAq3dkfHy1YDlnv2joc82HyQ%2Bi8; mediawiki_session=s0i4jb61ka5ckdhnfqoids1mjb9rl520
    DNT: 1
    ORIGIN: http://localhost
    REFERER: http://localhost/index.php/Special:UserLogin
    UPGRADE-INSECURE-REQUESTS: 1
    X-FORWARDED-FOR: <IP>
    X-FORWARDED-HOST: localhost
    X-FORWARDED-PORT: 80
    X-FORWARDED-PROTO: http
    X-FORWARDED-SERVER: 28ef83ab1502
    X-REAL-IP: <IP>
    [caches] cluster: APCUBagOStuff,WAN: mediawiki-main-default,stash: db-replicated,message: APCUBagOStuff,session: APCUBagOStuff
    [caches] LocalisationCache: using store LCStoreDB
    [DBConnection] Wikimedia\Rdbms\LoadBalancer::openConnection: calling initLB() before first connection.
    [DBReplication] Cannot use Chronologyprotector with EmptyBagOStuff.
    [DBReplication] Wikimedia\Rdbms\LBFactory::getchronologyprotector: using request info {
    "IPAddress": "172.18.0.2","UserAgent": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 10.15; rv:70.0) Gecko\/20100101 Firefox\/70.0","ChronologyProtection": false,"ChronologyPositionIndex": 0,"ChronologyClientId": null
    }
    [DBConnection] Wikimedia\Rdbms\LoadBalancer::openLocalConnection: connected to database 0 at 'maria-mediawiki'.
    [session] Session "s0i4jb61ka5ckdhnfqoids1mjb9rl520" requested without UserID cookie
    [MessageCache] MessageCache::load: Loading en-gb... local cache is empty,global cache is expired/volatile,loading from database
    Unstubbing $wgParser on call of $wgParser::firstCallInit from MessageCache->transform
    Parser: using preprocessor: Preprocessor_DOM
    Unstubbing $wgLang on call of $wgLang::_unstub from ParserOptions->__construct
    [MyAEGEEApi] providerAllowsAuthenticationDataChange called
    User::getBlockedStatus: checking...
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" data dirty due to dirty(): MediaWiki\Auth\AuthManager->setauthenticationSessionData/MediaWiki\Session\Session->setSecret/MediaWiki\Session\Session->getSecretKeys/MediaWiki\Session\Session->set/MediaWiki\Session\SessionBackend->dirty
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" data dirty due to dirty(): MediaWiki\Auth\AuthManager->setauthenticationSessionData/MediaWiki\Session\Session->setSecret/MediaWiki\Session\Session->getSecretKeys/MediaWiki\Session\Session->set/MediaWiki\Session\SessionBackend->dirty
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" data dirty due to dirty(): MediaWiki\Auth\ThrottlePreAuthenticationProvider->testForauthentication/MediaWiki\Auth\AuthManager->setauthenticationSessionData/MediaWiki\Session\Session->setSecret/MediaWiki\Session\Session->set/MediaWiki\Session\SessionBackend->dirty
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" save: dataDirty=1 metaDirty=0 forcePersist=0
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" data dirty due to dirty(): AuthManagerSpecialPage->performAuthenticationStep/MediaWiki\Auth\AuthManager->beginAuthentication/MediaWiki\Session\Session->setSecret/MediaWiki\Session\Session->set/MediaWiki\Session\SessionBackend->dirty
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" save: dataDirty=1 metaDirty=0 forcePersist=0
    [MyAEGEEApi] Got access token
    [MyAEGEEApi] Auth succeeded.
    [MyAEGEEApi] User succeeded: <user name>
    [authentication] Primary login with MyAEGEEApiPrimaryAuthenticationProvider succeeded
    [authentication] Auto-creating <user name> on login
    [authentication] MediaWiki\Auth\AuthManager::autoCreateUser: IP lacks the ability to create or autocreate accounts
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" data dirty due to dirty(): MediaWiki\Auth\AuthManager->beginAuthentication/MediaWiki\Auth\AuthManager->continueAuthentication/MediaWiki\Auth\AuthManager->autoCreateUser/MediaWiki\Session\Session->set/MediaWiki\Session\SessionBackend->dirty
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" save: dataDirty=1 metaDirty=0 forcePersist=0
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" data dirty due to dirty(): AuthManagerSpecialPage->performAuthenticationStep/MediaWiki\Auth\AuthManager->beginAuthentication/MediaWiki\Auth\AuthManager->continueAuthentication/MediaWiki\Session\Session->remove/MediaWiki\Session\SessionBackend->dirty
    [session] SessionBackend "s0i4jb61ka5ckdhnfqoids1mjb9rl520" save: dataDirty=1 metaDirty=0 forcePersist=0
    [authevents] Login attempt
    [MyAEGEEApi] providerAllowsAuthenticationDataChange called
    MediaWiki::preOutputCommit: primary transaction round committed
    MediaWiki::preOutputCommit: pre-send deferred updates completed
    MediaWiki::preOutputCommit: LBFactory shutdown completed

非常感谢您的回答。

wyuan123 回答:在MediaWiki中使用自定义PrimaryAuthenticationProvider登录时,“不允许自动创建帐户”

您可能应该禁用不需要的登录提供程序,而不是删除帐户创建权限。也就是说,$wgGroupPermissions['*']['autocreateaccount'] = true;应该足以使您的提供者正常工作,同时仍然禁止正常的帐户创建。

本文链接:https://www.f2er.com/3044702.html

大家都在问