草庐IT

php - 如何为 MediaWiki 设置外部单点登录?

coder 2024-04-21 原文

我正在尝试使用 ExtAuthDB 扩展为 MediaWiki 设置单点登录。目的是当用户登录主网站:www.mysite.com 时,自动从外部用户系统对用户进行身份验证。 Mediawiki 位于子域:www.wiki.mysite.com。

我已经按照指南中的说明安装了扩展程序。所有特权都是正确的。但它不起作用。

ExtAuthDB.php 是:

<?php
/**
* Authentication plugin interface. Instantiate a subclass of AuthPlugin
* and set $wgAuth to it to authenticate against some external tool.
*
* The default behavior is not to do anything, and use the local user
* database for all authentication. A subclass can require that all
* accounts authenticate externally, or use it only as a fallback; also
* you can transparently create internal wiki accounts the first time
* someone logs in who can be authenticated externally.
*
* This interface is a derivation of AuthJoomla and might change a bit before 1.4.0 final is done...
*
*/
$wgExtensionCredits['parserhook'][] = array (
'name' => 'ExtAuthDB',
'author' => 'Alessandra Bilardi',
'description' => 'Authenticate users about external MySQL database',
'url' => 'https://www.mediawiki.org/wiki/Extension:ExtAuthDB',
'version' => '0.1',
);

require_once ( "$IP/includes/AuthPlugin.php" );
class ExtAuthDB extends AuthPlugin
{

/**
* Add into LocalSettings.php the following code: 
*
* MySQL Host Name.
* $wgExtAuthDB_MySQL_Host = '';
* MySQL Username.      
* $wgExtAuthDB_MySQL_Username = '';
* MySQL Password.        
* $wgExtAuthDB_MySQL_Password = '';
* MySQL Database Name.    
* $wgExtAuthDB_MySQL_Database = '';
* MySQL Database Table of users data.
* $wgExtAuthDB_MySQL_Table = '';
* MySQL Database username column label.
* $wgExtAuthDB_MySQL_Login = '';
* MySQL Database login password column label
* $wgExtAuthDB_MySQL_Pswrd = '';
* MySQL Database email column label
* $wgExtAuthDB_MySQL_Email = '';
* MySQL Database user real name column label
* $wgExtAuthDB_MySQL_RealN = '';
* require_once("$IP/extensions/ExtAuthDB/ExtAuthDB.php");
* $wgAuth = new ExtAuthDB();
*
* @return Object Database
*/
private function connectToDB()
{
    $db = & Database :: newFromParams(
    $GLOBALS['wgExtAuthDB_MySQL_Host'],
    $GLOBALS['wgExtAuthDB_MySQL_Username'],
    $GLOBALS['wgExtAuthDB_MySQL_Password'],
    $GLOBALS['wgExtAuthDB_MySQL_Database']);

    $this->userTable = $GLOBALS['wgExtAuthDB_MySQL_Table'];
    $this->userLogin = $GLOBALS['wgExtAuthDB_MySQL_Login'];
    $this->userPswrd = $GLOBALS['wgExtAuthDB_MySQL_Pswrd'];//.$GLOBALS['$wgExtAuthDB_MySQL_Salt'];
    $this->userEmail = $GLOBALS['wgExtAuthDB_MySQL_Email'];
    $this->userRealN = $GLOBALS['wgExtAuthDB_MySQL_RealN'];
    wfDebug("ExtAuthDB::connectToDB() : DB failed to open\n");
    return $db;
}

/**
 * Check whether there exists a user account with the given name.
 * The name will be normalized to MediaWiki's requirements, so
 * you might need to munge it (for instance, for lowercase initial
 * letters).
 *
 * @param $username String: username.
 * @return bool
 * @public
 */
function userExists( $username ) {
    # Override this!
    return true;
}

/**
 * Check if a username+password pair is a valid login.
 * The name will be normalized to MediaWiki's requirements, so
 * you might need to munge it (for instance, for lowercase initial
 * letters).
 *
 * @param $username String: username.
 * @param $password String: user password.
 * @return bool
 * @public
 */
function authenticate( $username, $password )
{
    $db = $this->connectToDB();
    $hash_password = $db->selectRow($this->userTable,array ($this->userPswrd), array ($this->userLogin => $username ), __METHOD__ );
    if ($password == $hash_password->{$this->userPswrd}) {
        return true;
    }
    return false;
}

/**
 * Set the domain this plugin is supposed to use when authenticating.
 *
 * @param $domain String: authentication domain.
 * @public
 */
function setDomain( $domain ) {

    $this->domain = $domain;
}

/**
 * Check to see if the specific domain is a valid domain.
 *
 * @param $domain String: authentication domain.
 * @return bool
 * @public
 */
function validDomain( $domain ) {
    # Override this!
    return true;
}

/**
 * When a user logs in, optionally fill in preferences and such.
 * For instance, you might pull the email address or real name from the
 * external user database.
 *
 * The User object is passed by reference so it can be modified; don't
 * forget the & on your function declaration.
 *
 * @param User $user
 * @public
 */
function updateUser( &$user )
{
    $db = $this->connectToDB();
    $euser = $db->selectRow($this->userTable,array ( '*' ), array ($this->userLogin => $user->mName ), __METHOD__ );
    $user->setRealName($euser->{$this->userRealN});
    $user->setEmail($euser->{$this->userEmail});
    $user->mEmailAuthenticated = wfTimestampNow();
    $user->saveSettings();
    //exit;
    # Override this and do something
    return true;
}
function disallowPrefsEditByUser() {
    return array (
        'wpRealName' => true,
        'wpUserEmail' => true,
        'wpNick' => true
    );
}

/**
 * Return true if the wiki should create a new local account automatically
 * when asked to login a user who doesn't exist locally but does in the
 * external auth database.
 *
 * If you don't automatically create accounts, you must still create
 * accounts in some way. It's not possible to authenticate without
 * a local account.
 *
 * This is just a question, and shouldn't perform any actions.
 *
 * @return bool
 * @public
 */
function autoCreate() {
    return true;
}

/**
 * Can users change their passwords?
 *
 * @return bool
 */
function allowPasswordChange() {
    return false;
}

/**
 * Set the given password in the authentication database.
 * As a special case, the password may be set to null to request
 * locking the password to an unusable value, with the expectation
 * that it will be set later through a mail reset or other method.
 *
 * Return true if successful.
 *
 * @param $user User object.
 * @param $password String: password.
 * @return bool
 * @public
 */
function setPassword( $user, $password ) {
    return true;
}

/**
 * Update user information in the external authentication database.
 * Return true if successful.
 *
 * @param $user User object.
 * @return bool
 * @public
 */
function updateExternalDB( $user ) {
    $db = $this->connectToDB();
    $euser = $db->selectRow($this->userTable,array ( '*' ), array ($this->userLogin => $user->mName ), __METHOD__ );
    $user->setRealName($euser->{$this->userRealN});
    $user->setEmail($euser->{$this->userEmail});
    $user->mEmailAuthenticated = wfTimestampNow();
    $user->saveSettings();
    return true;
}

/**
 * Check to see if external accounts can be created.
 * Return true if external accounts can be created.
 * @return bool
 * @public
 */
function canCreateAccounts() {
    return false;
}

/**
 * Add a user to the external authentication database.
 * Return true if successful.
 *
 * @param User $user - only the name should be assumed valid at this point
 * @param string $password
 * @param string $email
 * @param string $realname
 * @return bool
 * @public
 */
function addUser( $user, $password, $email='', $realname='' ) {
    return false;
}


/**
 * 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;
}

/**
 * When creating a user account, optionally fill in preferences and such.
 * For instance, you might pull the email address or real name from the
 * external user database.
 *
 * The User object is passed by reference so it can be modified; don't
 * forget the & on your function declaration.
 *
 * @param $user User object.
 * @param $autocreate bool True if user is being autocreated on login
 * @public
 */
function initUser( $user, $autocreate=false ) {
    # Override this to do something.
}

/**
 * If you want to munge the case of an account name before the final
 * check, now is your chance.
 */
function getCanonicalName( $username ) {
    return $username;
}
}

在 LocalSettings.php 中,我应该添加以下代码:

// add ExtAuthDB
// MySQL Host Name.
$wgExtAuthDB_MySQL_Host = 'localhost';
// MySQL Username.
$wgExtAuthDB_MySQL_Username = 'dbuser';
// MySQL Password.
$wgExtAuthDB_MySQL_Password = 'dbpassword';
// MySQL Database Name.
$wgExtAuthDB_MySQL_Database = 'base';
// MySQL Database Table of users data.
$wgExtAuthDB_MySQL_Table = 'members';
// MySQL Database username column label.
$wgExtAuthDB_MySQL_Login = 'username';
// MySQL Database login password column label
$wgExtAuthDB_MySQL_Pswrd = 'password';
$wgExtAuthDB_MySQL_Salt='salt';
// MySQL Database email column label
$wgExtAuthDB_MySQL_Email = 'email';
// MySQL Database user real name column label
$wgExtAuthDB_MySQL_RealN = 'real_name';

require_once("$IP/extensions/ExtAuthDB/ExtAuthDB.php");
$wgAuth = new ExtAuthDB();

对不起,我不得不复制完整的脚本,因为我不知道确切的错误在哪里。我的问题是:为什么它不起作用?哪里错了?

编辑:

我的外部用户表由 id、用户名、密码、salt、email、real_name 组成。我认为这可能是因为单独的密码和盐字段,所以我尝试在 ExtAuthDB.php 文件中手动实现盐。不幸的是,它也没有用。然后我评论了这一行。

最佳答案

我能够使用 OAuth 2.0 服务器设置从 WordPress 到媒体维基的 SSO(单点登录),我已经发布了我的解决方案 on this post

或者您可以按照以下步骤操作:

  1. 首先您需要一个 OAuth 2.0 服务器,您可以自己实现它,请在此处查看详细信息 Run your own OAuth 2.0 Server或者最简单的方法是使用 WordPress 插件 WP Oauth 2.0 server您不必购买专业版,您也可以通过使用授权类型 Authorization codes 来实现 SSO这是免费的。

  2. 您需要在您的媒体 wiki 上安装 OAuth 2.0 客户端扩展,该扩展可以在 here 中找到,按照那里的安装说明进行操作。

  3. 转到 WordPress 插件页面并激活 OAuth 服务器,然后导航到 OAuth 服务器并添加一个新客户端,为您的客户端命名并在重定向 URI 中添加媒体维基扩展页面上的链接提及,即 http://your.wiki.domain/path/to/wiki/Special:OAuth2Client/callback ,然后转到 OAuth>clients 页面,您可以在其中看到新创建的客户端,单击编辑,在这里您可以看到 clientIDClient secretlocalSettings.php 中添加此 ID 和密码您的媒体 wiki。

  4. 在 WordPress 上创建一个页面,并在其中放置以下带有您的客户 ID 的按钮

    < a href="https://your-Domain-Where-OAuth-server-is-running.de/oauth/authorize?response_type=code&client_id=YOURCLIENTID&state=RANDOM-STRING&scope=basic"> go to wiki</a> 别忘了输入 scope否则你会得到一个媒体 wiki 内部错误。

  5. 如果一切正常,那么在从您的 WordPress 单击此按钮后,您应该会自动转到媒体 wiki 主页。 media wiki 将显示您已登录。我花了一些时间才弄清楚我希望这对来到这里的任何人有所帮助。

关于php - 如何为 MediaWiki 设置外部单点登录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32955108/

有关php - 如何为 MediaWiki 设置外部单点登录?的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  3. ruby - 如何为 emacs 安装 ruby​​-mode - 2

    我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby​​提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs

  4. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  5. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  6. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  7. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  8. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  9. ruby - 从外部访问类的实例变量 - 2

    我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内

  10. ruby-on-rails - 如何为空白字段编写 rspec? [Rails3.1] - 2

    我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona

随机推荐