Mediawiki验证替换显示“需要登录”而不是将用户签名到维基

时间:2011-06-24 00:02:50

标签: php authentication mediawiki

我对MediaWiki很公平,并且需要一种方法来在用户认证到中央服务器(为应用程序创建会话和cookie)之后自动登录用户。

我根据LDAP Authentication扩展名和few others编写了自定义身份验证扩展程序。扩展只需要读取一些会话数据来创建或更新用户,然后自动登录。所有身份验证都在外部处理。如果没有外部登录,用户甚至无法访问wiki网站。

此扩展程序已投入生产,取代了旧的标准MediaWiki身份验证系统。我还合并了用户帐户以准备更改。默认情况下,用户必须登录才能在Wiki中查看,编辑或以其他方式执行任何操作。

我的问题是我发现如果用户以前使用过内置的MediaWiki身份验证系统并返回到wiki,我的扩展程序会尝试自动登录用户,但是,他们会看到“需要登录”页面而不是他们要求的页面,就像他们是匿名用户。如果用户然后刷新页面,他们将能够导航,编辑等。

据我所知,这个问题在重置或创建新用户ID后自行解决(但有时会出现奇怪的问题)。要复制,如果“USERID”cookie中存在较旧的用户ID,则会向用户显示“需要登录”页面,这是一个糟糕的用户体验。显示此页面的另一种方法是从数据库中删除用户帐户并刷新Wiki页面。因此,用户将再次看到“需要登录”页面。

有没有人知道如何使用调试来找出为什么MediaWiki认为用户没有在正确设置cookie时登录用户并且所需要的只是页面刷新?

这是我的扩展(这篇文章简化了一点):

<?php

$wgExtensionCredits['parserhook'][] = array (
    'name' => 'MyExtension',
    'author' => '',
);

if (!class_exists('AuthPlugin')) {
    require_once ( 'AuthPlugin.php' );
}

class MyExtensionPlugin extends AuthPlugin {

    function userExists($username) {
        return true;
    }

    function authenticate($username, $password) {

        $id = $_SESSION['id'];
        if($username = $id) {
          return true;
        } else {
          return false;
        }

    }

    function updateUser(& $user) {
        $name = $user->getName();
        $user->load();

        $user->mPassword = ''; 
        $user->mNewpassword = '';
        $user->mNewpassTime = null;

        $user->setRealName($_SESSION['name']);
        $user->setEmail($_SESSION['email']);
        $user->mEmailAuthenticated = wfTimestampNow();
        $user->saveSettings();

        return true;
    }

    function modifyUITemplate(& $template) { 
        $template->set('useemail', false); 
        $template->set('remember', false); 
        $template->set('create', false); 
        $template->set('domain', false); 
        $template->set('usedomain', false); 
    } 

    function autoCreate() {
        return true;
    }

    function disallowPrefsEditByUser() {
        return array (
            'wpRealName' => true,
            'wpUserEmail' => true,
            'wpNick' => true
        );
    }

    function allowPasswordChange() {
        return false;
    }


    function setPassword( $user, $password ) {
        return false;
    }


    function strict() {
        return true;
    }

    function initUser( & $user ) {
    }

    function updateExternalDB( $user ) {
        return false;
    }

    function canCreateAccounts() {
        return false;
    }

    function addUser( $user, $password ) {
        return false;
    }

    function getCanonicalName( $username ) {
        return $username;
    }
}


function SetupAuthMyExtension() {
    global $wgHooks;
    global $wgAuth;

    $wgHooks['UserLoadFromSession'][] = 'Auth_MyExtension_autologin_hook';
    $wgHooks['UserLogoutComplete'][] = 'Auth_MyExtension_UserLogoutComplete';
    $wgHooks['PersonalUrls'][] = 'Auth_MyExtension_personalURL_hook';
    $wgAuth = new MyExtensionPlugin();
}

function Auth_MyExtension_autologin_hook($user, &$return_user ) {
    global $wgUser;
    global $wgAuth;
    global $wgContLang;

    wfSetupSession();

    // Give us a user, see if we're around
    $tmpuser = new User() ;
    $rc = $tmpuser->newFromSession();
    $rc = $tmpuser->load();

    if( $rc && $rc->isLoggedIn() ) {
        if ( $rc->authenticate($rc->getName(), '') ) {
            return true;
        } else {
            $rc->logout();
        }
    }

    $id = trim($_SESSION['id']);
    $name = ucfirst(trim($_SESSION['name']));

    if (empty($dsid)) {
        $result = false;    // Deny access
        return true;
    }

    $user = User::newFromName($dsid);

    if (0 == $user->getID() ) {
        // we have a new user to add...     
        $user->setName( $id);
        $user->addToDatabase();
        $user->setToken();
            $user->saveSettings();

        $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
        $ssUpdate->doUpdate();

    } else {
        $user->saveToCache();
    }

    // update email, real name, etc.
    $wgAuth->updateUser( $user );

    $result = true;
    // Go ahead and log 'em in
    $user->setToken();
    $user->saveSettings();
    $user->setupSession();
    $user->setCookies();    
    return true;

}

function Auth_MyExtension_personalURL_hook(& $personal_urls, & $title) {
    global $wgUser;
    unset( $personal_urls['mytalk'] );
    unset($personal_urls['Userlogin']);
    $personal_urls['userpage']['text'] = $wgUser->getRealName();

    foreach (array('login', 'anonlogin') as $k) {
        if (array_key_exists($k, $personal_urls)) {
            unset($personal_urls[$k]);
        }
    }
    return true;
}


function Auth_MyExtension_UserLogoutComplete(&$user, &$inject_html, $old_name) { 
    setcookie( $GLOBALS['wgCookiePrefix'] . '_session', '', time() - 3600, $GLOBALS['wgCookiePath']);
    setcookie( $GLOBALS['wgCookiePrefix'] . 'UserName', '', time() - 3600, $GLOBALS['wgCookiePath']);
    setcookie( $GLOBALS['wgCookiePrefix'] . 'UserID', '', time() - 3600, $GLOBALS['wgCookiePath']);
    setcookie( $GLOBALS['wgCookiePrefix'] . 'Token', '', time() - 3600, $GLOBALS['wgCookiePath']);
    return true;
}


?>

以下是我的LocalSettings.php文件的一部分:

#############################
# Disallow Anonymous Access
#############################
$wgGroupPermissions['*']['read']            = false;
$wgGroupPermissions['*']['edit']            = false;
$wgGroupPermissions['*']['createpage']      = false;
$wgGroupPermissions['*']['createtalk']      = false;
$wgGroupPermissions['*']['createaccount']   = false;
$wgShowIPinHeader = false; # For non-logged in users

#############################
# Extension: MyExtension
#############################
require_once("$IP/extensions/MyExtension.php");
$wgAutoLogin = true;
SetupAuthMyExtension();
$wgDisableCookieCheck = true;

1 个答案:

答案 0 :(得分:0)

我发现了这个问题发生的原因。当用户先前已登录到wiki时,设置了具有旧用户ID的旧cookie。 Mediawiki试图读取此cookie并发现它与数据库不匹配,因此出于安全考虑,向用户显示了“需要登录”页面。

要通过此问题,用户只需刷新页面,在登录前清除其Cookie,或者管理员可以允许访客访问读取页面。

或者,可以临时更改核心文件集以绕过检查。