&引用;不允许自动创建帐户";在MediaWiki中使用自定义PrimaryAuthenticationProvider登录时

&引用;不允许自动创建帐户";在MediaWiki中使用自定义PrimaryAuthenticationProvider登录时,mediawiki,mediawiki-extensions,Mediawiki,Mediawiki Extensions,我正在使用MediaWiki编写一个自定义PrimaryAuthenticationProvider,用于针对我的API而不是MediaWiki数据库进行授权。但是,当我以以下方式关闭LocalSettings.php中的自动创建时: $wgGroupPermissions['*']['createaccount'] = false; $wgGroupPermissions['*']['edit'] = false; $wgGroupPermissions['*']['read'] = fals

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

$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['read'] = false;
当我尝试使用正确的凭据登录API时,请求失败,错误为:
自动创建本地帐户失败:不允许自动创建帐户。

我想我没有存根一个函数,它应该返回正确的值,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, true);
        curl_setopt($ch, 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,
            'password'=>$password
        ));

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Accept: application/json',
            '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, failing.' );
            return null;
        }

        $response_parsed = json_decode($response);
        if (!$response_parsed->success) {
            wfDebugLog( 'MyAEGEEApi', '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, $creator, array $reqs ) {
        wfDebugLog( 'MyAEGEEApi', 'beginPrimaryAccountCreation called');
        return AuthenticationResponse::newAbstain();
    }

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

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

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

按预期工作。谢谢!工作如期进行。谢谢!

    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