从 WordPress 单点登录到媒体维基

Single Sign On from WordPress to media wiki

我正在尝试创建从 Wordpress 到 MediaWiki 的单点登录。我的 WordPress(WordPress 插件)上有 WPOauthServer 运行。在我的 wiki 上,我安装了 Extension:OAuth2 Client。我希望我的用户只登录到 WordPress,然后他们可以从那里访问 wiki,而无需再次登录 wiki。 WPOauthServer 工作正常,我使用的是授权类型 Authorization Code。我已经使用 curl 进行了测试,我能够获取授权码,使用授权码我可以获得身份验证令牌。

我的 wordpress 页面上有一个按钮,客户端 ID:

<a href="https://xxxxxx.de/oauth/authorize?response_type=code&client_id=XXXXXXXXX&state=123">Connect Your Account</a>

当我打开授权 link 时,我被重定向到服务器端客户端设置中设置的以下 redirect-URI

https://wiki.XXXXXXXXXXXXX.de/wiki/Special:OAuth2Client/callback?code=farkmm4ttuwxnne8a9firwtdikmite788hwpyhzg&state=123 

这里我得到一个内部错误:

Fatal exception of type "GuzzleHttp\Exception\RequestException

经过挖掘我发现这个异常是在 sendRequest 函数中的扩展文件 AbstractProvider.php 中引起的:

/**
 * Sends a request instance and returns a response instance.
 *
 * @param  RequestInterface $request
 * @return ResponseInterface
 */
protected function sendRequest(RequestInterface $request)
{
    try {
        var_dump($request);
        $response = $this->getHttpClient()->send($request);
        var_dump($response);
    } catch (BadResponseException $e) {
        $response = $e->getResponse();
    }
    return $response;
}

异常发生在$response = $this->getHttpClient()->send($request);

我认为我的请求可能有问题,根据请求执行 var_dump 显示以下内容:

/var/www/mediawiki/w/extensions/MW-OAuth2Client/vendors/oauth2-client/src/Provider/AbstractProvider.php:629:
object(GuzzleHttp\Psr7\Request)[278]
  private 'method' => string 'POST' (length=4)
  private 'requestTarget' => null
  private 'uri' => 
    object(GuzzleHttp\Psr7\Uri)[279]
      private 'scheme' => string 'https' (length=5)
      private 'userInfo' => string '' (length=0)
      private 'host' => string 'xxxxxxx.de' (length=13)
      private 'port' => null
      private 'path' => string '/oauth/token/' (length=13)
      private 'query' => string '' (length=0)
      private 'fragment' => string '' (length=0)
  private 'headers' => 
    array (size=2)
      'Host' => 
        array (size=1)
          0 => string 'xxxxxx.de' (length=13)
      'content-type' => 
        array (size=1)
          0 => string 'application/x-www-form-urlencoded' (length=33)
  private 'headerNames' => 
    array (size=2)
      'content-type' => string 'content-type' (length=12)
      'host' => string 'Host' (length=4)
  private 'protocol' => string '1.1' (length=3)
  private 'stream' => 
    object(GuzzleHttp\Psr7\Stream)[287]
      private 'stream' => resource(18, stream)
      private 'size' => null
      private 'seekable' => boolean true
      private 'readable' => boolean true
      private 'writable' => boolean true
      private 'uri' => string 'php://temp' (length=10)
      private 'customMetadata' => 
        array (size=0)
          empty

来自 Apache 日志的堆栈跟踪:

 Notice:  Undefined index: scopes in /var/www/mediawiki/w/extensions/MW-OAuth2Client/SpecialOAuth2Client.php on line 54, referer: https://XXXXXXerv.de/sso-test/
 Stack trace:, referer: https://XXXXXXerv.de/sso-test/
   1. {main}() /var/www/mediawiki/w/index.php:0, referer: https://XXXXXXerv.de/sso-test/
   2. MediaWiki->run() /var/www/mediawiki/w/index.php:42, referer: https://XXXXXXerv.de/sso-test/
   3. MediaWiki->main() /var/www/mediawiki/w/includes/MediaWiki.php:524, referer: https://XXXXXXerv.de/sso-test/
   4. MediaWiki->performRequest() /var/www/mediawiki/w/includes/MediaWiki.php:861, referer: https://XXXXXXerv.de/sso-test/
   5. SpecialPageFactory::getPage() /var/www/mediawiki/w/includes/MediaWiki.php:255, referer: https://XXXXXXerv.de/sso-test/
   6. SpecialOAuth2Client->__construct() /var/www/mediawiki/w/includes/specialpage/SpecialPageFactory.php:382, referer: https://XXXXXXerv.de/sso-test/
 Notice:  Undefined index: scopes in /var/www/mediawiki/w/extensions/MW-OAuth2Client/SpecialOAuth2Client.php on line 54, referer: https://XXXXXXerv.de/sso-test/
 Stack trace:, referer: https://XXXXXXerv.de/sso-test/
   1. {main}() /var/www/mediawiki/w/index.php:0, referer: https://XXXXXXerv.de/sso-test/
   2. MediaWiki->run() /var/www/mediawiki/w/index.php:42, referer: https://XXXXXXerv.de/sso-test/
   3. MediaWiki->main() /var/www/mediawiki/w/includes/MediaWiki.php:524, referer: https://XXXXXXerv.de/sso-test/
   4. MediaWiki->performRequest() /var/www/mediawiki/w/includes/MediaWiki.php:861, referer: https://XXXXXXerv.de/sso-test/
   5. SpecialPageFactory::executePath() /var/www/mediawiki/w/includes/MediaWiki.php:288, referer: https://XXXXXXerv.de/sso-test/
   6. SpecialPageFactory::getPage() /var/www/mediawiki/w/includes/specialpage/SpecialPageFactory.php:513, referer: https://XXXXXXerv.de/sso-test/
   7. SpecialOAuth2Client->__construct() /var/www/mediawiki/w/includes/specialpage/SpecialPageFactory.php:382, referer: https://XXXXXXerv.de/sso-test/

编辑: 从堆栈跟踪中,我意识到 scope 未在 localsettings.php 的 media wiki 客户端设置中定义,因此在设置范围后我没有在 apache 日志中收到任何错误,但 media wiki 仍然显示内部错误 Fatal exception of type "GuzzleHttp\Exception\RequestException

经过更多挖掘,我发现我遇到了一个 curl: (60) SSL certificate: unable to get local issuer certificate 错误,我通过将 CA 根添加到我信任的 CA 解决了这个错误,有关详细信息,请参阅 this post

解决这个问题后,我只需要更正以下内容:

$wgOAuth2Client['configuration']['username'] = 'user_login'; // JSON path to username
$wgOAuth2Client['configuration']['email'] = 'user_email'; // JSON path to email

查看从 WordPress 实施 SSO 的答案

我能够按照以下步骤设置从 WordPress 到媒体 wiki 的 SSO(单点登录):

  1. 首先您需要一个 OAuth 2.0 服务器,您可以自己实现它,请在此处查看详细信息Run your own OAuth 2.0 Server or the easiest way is to use the WordPress plugin WP Oauth 2.0 server您不必购买专业版,您也可以通过使用授予类型 Authorization codes 免费提供。

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

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

  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 否则你会得到一个媒体维基内部错误。

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

我按照 Ahmad 上面的回答进行了部分操作。但是,我不得不更改一行源代码并另外配置媒体 wiki 的 LocalSettings,如最初发布在这里:https://www.mediawiki.org/wiki/Topic:Ux1crr4vosyw0tjl

为方便起见重复: 我终于通过这些额外的步骤得到了它 - 编辑我的 LocalSettings.php; xxxx 是我的网站,以 https://

开头

除了设置密码和 ID 外,我还必须使用这些设置填写配置参数 - 这些来自我的站点。

$wgOAuth2Client['configuration']['authorize_endpoint'] = 'xxxx/oauth/authorize'; //授权URL

$wgOAuth2Client['configuration']['access_token_endpoint'] = 'xxxx/oauth/token'; // 代币 URL

$wgOAuth2Client['configuration']['api_endpoint'] = 'xxxx/oauth/me?access_token='; // URL 获取用户 JSON

$wgOAuth2Client['configuration']['redirect_uri'] = 'xxxx/mediawiki/index.php?title=Special:OAuth2Client/redirect&returnto=Special%3AUserLogin';

$wgOAuth2Client['configuration']['username'] = 'user_login'; // JSON 用户名路径

$wgOAuth2Client['configuration']['email'] = 'user_email'; // JSON 电子邮件路径

$wgOAuth2Client['configuration']['scopes'] = 'openid email profile'; //权限

$wgWhitelistRead = array("Special:OAuth2Client");

然后我还必须在.../mediawiki/extensions/MW-OAuth2Client/vendors/oauth2-client/src/Provider/AbstractProvider.php

中更改一处代码

受保护的函数 fetchResourceOwnerDetails(AccessToken $token)

{

    $url = $this->getResourceOwnerDetailsUrl($token);

    // Added this line so we can build the url request properly otherwise it didn't append the token to the api_endpoint

    $url = $url . $token;

    $request = $this->getAuthenticatedRequest(self::METHOD_GET, $url, $token);

    return $this->getResponse($request);

}

之后插件按预期运行。

关于安装 mediawiki 扩展的注意事项我收到了这些作曲家警告 - 我相信可以安全地忽略它们...

包guzzle/guzzle已废弃,您应该避免使用它。请改用 guzzlehttp/guzzle。

包phpunit/phpunit-mock-objects已废弃,您应该避免使用它。没有建议更换。

包satooshi/php-coveralls已废弃,您应该避免使用它。请改用 php-coveralls/php-coveralls。

我还发现这个 link 有助于理解如何使用 wordpress 插件:https://wp-oauth.com/docs/how-to/setup-wp-oauth-server-for-single-sign-on-with-wordpress/

而且我发现您可以从站点的 WP 管理页面将 OAUTH 插件添加到 wordpress - 只需单击“添加插件”按钮 - 或通过 WP Oauth Server 搜索 "oath" 无需获取它从他们的 WP OATH 网站上只能找到付费版本。