从WordPress到MediaWiki的单点登录

3
我正在尝试从WordPress到MediaWiki创建单点登录。我在WordPress上运行WPOauthServer(WordPress插件)。在我的维基上,我安装了 扩展程序:OAuth2客户端 。我希望我的用户只需登录WordPress即可前往维基,无需再次登录。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>

当我打开授权链接时,我被重定向到服务器端客户端设置中所设置的以下redirect-URI页面:
https://wiki.XXXXXXXXXXXXX.de/wiki/Special:OAuth2Client/callback?code=farkmm4ttuwxnne8a9firwtdikmite788hwpyhzg&state=123 

在这里,我遇到了一个内部错误:

Fatal exception of type "GuzzleHttp\Exception\RequestException

深入研究后,我发现这个异常是由扩展文件AbstractProvider.php中的sendRequest函数引起的:

/**
 * 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/
编辑: 根据堆栈跟踪,我意识到在localsettings.php中的mediawiki客户端设置中未定义scope,因此在设置了范围之后,我的apache日志中没有任何错误,但是mediawiki仍然显示内部错误,Fatal exception of type "GuzzleHttp\Exception\RequestException
更深入地挖掘后,我发现出现了curl: (60) SSL certificate: unable to get local issuer certificate错误,通过将CA根添加到我的受信任CA中解决了这个问题,有关更多信息,请参见此帖子
解决了这个问题后,我只需要纠正以下内容即可:
$wgOAuth2Client['configuration']['username'] = 'user_login'; // JSON path to username
$wgOAuth2Client['configuration']['email'] = 'user_email'; // JSON path to email

请参见有关从WordPress实施SSO的答案。

最近MediaWiki从php-curl转换到Guzzle作为请求客户端库,这可能会破坏OAuth2 Client扩展。然而,在采取任何行动之前,您需要获取更多有用的错误信息。我建议在https://phabricator.wikimedia.org上提交一个错误报告,并提供维基的版本信息和至少一个堆栈跟踪。 - Tgr
同时也添加了Apache日志的堆栈跟踪,但扩展使用的是 guzzlehttp,命名空间为 League\OAuth2\Client\Provider; - Ahmad Karim
Apache日志并不是非常可靠的,你应该配置MediaWiki自己的日志记录 - Tgr
2个回答

3

我通过以下步骤成功地将WordPress与MediaWiki进行了SSO(单点登录)设置:

  1. 首先,您需要一个OAuth 2.0服务器,您可以自己实现(详情请参见运行您自己的OAuth 2.0服务器),或者最简单的方法是使用WordPress插件WP OAuth 2.0服务器。您不必购买专业版,您也可以使用免费的授权码(Grant type)实现SSO。

  2. 您需要在MediaWiki上安装OAuth 2.0客户端扩展程序,该扩展程序可以在此处找到,请按照那里的安装说明操作。

  3. 转到WordPress插件页面并激活OAuth服务器,然后导航到OAuth服务器并添加新客户端,在Redirect URI中添加在MediaWiki扩展程序页面上提及的链接,即 http://your.wiki.domain/path/to/wiki/Special:OAuth2Client/callback,然后进入OAuth>clients页面,您可以看到您新创建的客户端。点击编辑,这里您可以看到clientIDClient secret,将其添加到您的MediaWiki的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"> 去维基百科</a> 不要忘记加上scope,否则您将收到MediaWiki内部错误。

  5. 如果一切正常,则在从WordPress单击此按钮后,您应该自动进入MediaWiki主页。MediaWiki将显示您已登录。我花了一些时间才摸索出来,希望这可以帮助任何来这里的人。


1
OAuth>clients页面在哪里?我在维基的主页右上角点击了“OAuth2登录”,但是出现了500错误。 - Christos Hayward
您的WordPress上的Oauth>客户端页面。 - Ahmad Karim

1
I followed Ahmad's answer above and made a one line source code change. Additionally, I configured LocalSettings for media wiki as originally posted here: https://www.mediawiki.org/wiki/Topic:Ux1crr4vosyw0tjl.
To fill in the configuration parameters with settings from my site, I had to set the secret and ID. These are the additional steps I took: $wgOAuth2Client['configuration']['authorize_endpoint'] = 'xxxx/oauth/authorize'; // Authorization URL $wgOAuth2Client['configuration']['access_token_endpoint'] = 'xxxx/oauth/token'; // Token URL $wgOAuth2Client['configuration']['api_endpoint'] = 'xxxx/oauth/me?access_token='; // URL to fetch user 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 中进行一次代码更改。

protected function 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扩展时,请注意我收到了这些composer警告 - 我相信它们可以被安全忽略...

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

包phpunit/phpunit-mock-objects已经被弃用,您应该避免使用它。没有建议替代品。

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

此外,我发现这个链接很有用,可以帮助理解如何使用wordpress插件:https://wp-oauth.com/docs/how-to/setup-wp-oauth-server-for-single-sign-on-with-wordpress/

我发现您可以从网站的WP管理页面向wordpress添加OAUTH插件 - 只需点击“添加插件”按钮 - 或通过WP Oauth Server搜索“oath”。没有必要从他们的WP OATH网站获取它,那里只能找到付费版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接