我对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;
答案 0 :(得分:0)
我发现了这个问题发生的原因。当用户先前已登录到wiki时,设置了具有旧用户ID的旧cookie。 Mediawiki试图读取此cookie并发现它与数据库不匹配,因此出于安全考虑,向用户显示了“需要登录”页面。
要通过此问题,用户只需刷新页面,在登录前清除其Cookie,或者管理员可以允许访客访问读取页面。
或者,可以临时更改核心文件集以绕过检查。