PHP Guzzle 无法解析本地主机上的主机,但可以在服务器上运行

标签 php azure zend-framework2 guzzle

我有这个 Zend 2 应用程序,我正在其中使用 this Azure AD library用于身份验证。几个月来一切都工作正常,但突然它在我的本地主机上停止工作。奇怪的是它在我们的服务器上仍然运行良好。我不认为这是库本身的问题,这就是我在这里寻求帮助的原因。

每当我尝试使用以下代码获取 oauth2 的提供程序时:
(这个Azure类只是League\OAuth2\Client\Provider的扩展)

private static function getAzureProvider(): Azure
{
  $provider = new Azure([
     'clientId' => self::$azure_client_id,
     'clientSecret' => self::$azure_client_secret,
     'redirectUri' => self::$post_login_redirect_uri,
     'tenant' => self::$azure_tenant_id,
     'defaultEndPointVersion' => Azure::ENDPOINT_VERSION_2_0
  ]);
  $baseGraphUri = $provider->getRootMicrosoftGraphUri(null); // <-- This is what triggers the 'Could not resolve' error
  $provider->scope = 'openid profile email offline_access ' . $baseGraphUri . '/User.Read';
  return $provider;
}

我收到以下错误:

Error while obtaining AzureProvider: 'cURL error 6: Could not resolve host: login.microsoftonline.com (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)'.
Stacktrace: 
#0 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(155): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(105): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php(43): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php(28): GuzzleHttp\Handler\CurlHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#4 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php(51): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#5 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php(37): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#6 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Middleware.php(29): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#7 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php(70): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#8 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Middleware.php(59): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#9 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/HandlerStack.php(71): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#10 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Client.php(351): GuzzleHttp\HandlerStack->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#11 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Client.php(112): GuzzleHttp\Client->transfer(Object(GuzzleHttp\Psr7\Request), Array)
#12 /var/www/hqcrs/vendor/guzzlehttp/guzzle/src/Client.php(129): GuzzleHttp\Client->sendAsync(Object(GuzzleHttp\Psr7\Request), Array)
#13 /var/www/hqcrs/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(608): GuzzleHttp\Client->send(Object(GuzzleHttp\Psr7\Request))
#14 /var/www/hqcrs/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(621): League\OAuth2\Client\Provider\AbstractProvider->getResponse(Object(GuzzleHttp\Psr7\Request))
#15 /var/www/hqcrs/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php(76): League\OAuth2\Client\Provider\AbstractProvider->getParsedResponse(Object(GuzzleHttp\Psr7\Request))
#16 /var/www/hqcrs/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php(163): TheNetworg\OAuth2\Client\Provider\Azure->getOpenIdConfiguration('[tenant id]', '2.0')
#17 /var/www/hqcrs/module/Auth/src/Auth/Utils/AzureAuthUtils.php(74): TheNetworg\OAuth2\Client\Provider\Azure->getRootMicrosoftGraphUri(NULL)
#18 /var/www/hqcrs/module/Auth/src/Auth/Utils/AzureAuthUtils.php(91): AzureAuthUtils::getAzureProvider()
#19 /var/www/hqcrs/module/Auth/src/Auth/Utils/AzureAuthUtils.php(125): AzureAuthUtils::azureLogin()
#20 /var/www/hqcrs/module/Auth/src/Auth/Controller/AuthController.php(15): AzureAuthUtils::doAzureLogin()
#21 /var/www/hqcrs/vendor/zendframework/zend-mvc/src/Controller/AbstractActionController.php(82): Auth\Controller\AuthController->loginAction()
#22 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#23 /var/www/hqcrs/vendor/zendframework/zend-eventmanager/src/EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#24 /var/www/hqcrs/vendor/zendframework/zend-eventmanager/src/EventManager.php(211): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#25 /var/www/hqcrs/vendor/zendframework/zend-mvc/src/Controller/AbstractController.php(118): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#26 /var/www/hqcrs/vendor/zendframework/zend-mvc/src/DispatchListener.php(93): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#27 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#28 /var/www/hqcrs/vendor/zendframework/zend-eventmanager/src/EventManager.php(490): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#29 /var/www/hqcrs/vendor/zendframework/zend-eventmanager/src/EventManager.php(211): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent),     Object(Closure))
#30 /var/www/hqcrs/vendor/zendframework/zend-mvc/src/Application.php(314): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#31 /var/www/hqcrs/public/index.php(40): Zend\Mvc\Application->run()
#32 {main}

我已经在网上搜索了一整天,但似乎找不到任何具体的解决方案来解决这个问题。有人知道会发生什么吗?

如果我手动执行curl命令并转到https://login.microsoftonline.com,它似乎工作正常。 我在本地主机和服务器上的 cURL 版本都是 7.64.0,因此两者之间没有区别。如果我应该提供更多信息,请告诉我!

编辑:我的更多源代码如下:

    public static function isLoggedInWithAzure(?string $code = null, ?string $state = null): bool
    {
        return !empty(self::getAzureAccessToken($code, $state);
    }

    public static function doAzureLogin(?string $code = null, ?string $state = null)
    {
        if (!self::isLoggedInWithAzure($code, $state)) {
            self::azureLogin();
        }
    }

    private static function azureLogin()
    {
        $azure_provider = self::getAzureProvider();
        $oauth_session = new Container('oAuth2');
        $authorizationUrl = $azure_provider->getAuthorizationUrl(['scope' => $azure_provider->scope]);
        $oauth_session->state = $azure_provider->getState();
        header('Location: ' . $authorizationUrl);
        exit;
    }

    private static function getAzureAccessToken(?string $code = null, ?string $state = null): ?AccessToken
    {
        $oauth_session = new Container('oAuth2');
        $access_token = null;

        if ($code !== null && $state !== null && isset($oauth_session->state)) {
            /*
             * If code & state are set, try to get new accesstoken
             */
            if ($state == $oauth_session->state) {
                unset($oauth_session->state);

                /**
                 * Try to get an access token (using the authorization code grant)
                 *
                 * @var AccessToken $access_token
                 */
                $azure_provider = self::getAzureProvider();
                $access_token = $azure_provider->getAccessToken('authorization_code', [
                    'scope' => $azure_provider->scope,
                    'code' => $_GET['code'],
                ]);
            } else {
                self::writeToApplicationLog(CONST_APPLICATION_LOG_TYPE_ERROR, '[getAzureAccessToken] Invalid state returned.');
            }
        } else if (!empty($oauth_session->access_token)) {
            /*
             * Else if access token is set in session, verify if still valid
             */
            $access_token = $oauth_session->access_token;

            /**
             * @var AccessToken $access_token
             */
            if ($access_token->hasExpired()) {
                if ($access_token->getRefreshToken() !== null) {
                    $azure_provider = self::getAzureProvider();
                    $access_token = $azure_provider->getAccessToken('refresh_token', [
                        'scope' => $azure_provider->scope,
                        'refresh_token' => $access_token->getRefreshToken()
                    ]);
                } else {
                    self::writeToApplicationLog(CONST_APPLICATION_LOG_TYPE_ERROR, '[getAzureAccessToken] Accesstoken has expired but does not have refreshtoken. Accesstoken: ' . print_r($access_token, true));
                }
            }
        }

        $oauth_session->access_token = $access_token;
        return $access_token;
    }

最佳答案

错误如下:

Could not resolve host: login.microsoftonline.com

正如您所说,应用程序几个月前运行良好,我认为如果您清除 Artisan 中的所有类型的缓存,它也会运行良好。同时运行以下命令,然后再次重新启动服务器。

php artisan route:clear
php artisan config:clear
php artisan cache:clear

尝试更改用于初始化 Azure AAD 的 oauth 提供程序的代码。以下代码片段展示了如何做到这一点。

$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
'clientId' => 'c9e*****9ea',
'clientSecret' => 'AKX********',
'redirectUri' => 'http://localhost:90',
'tenant' => 'e2*******3d',
'urlAuthorize' => 'https://login.microsoftonline.com/e2*******3d/oauth2/v2.0/authorize',
'urlAccessToken' => 'https://login.microsoftonline.com/e2******3d/oauth2/v2.0/token',
'urlAPI' => 'b37*******b02',
'scope' => 'b37*******b02/.default'
]);
$provider->defaultEndPointVersion = TheNetworg\OAuth2\Client\Provider\Azure::ENDPOINT_VERSION_2_0;

现在您可以使用以下代码检索访问 token 。

$accessToken = $provider->getAccessToken('client_credentials', [
'scope'=> $provider->scope
]);

您应该阅读此Accessing AAD OAuth2 protected API from PHP文档以获取更多信息。

关于PHP Guzzle 无法解析本地主机上的主机,但可以在服务器上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69811820/

相关文章:

php - 如何在 Zend Framework 2 中使用 tableGateway 进行 MATCH AGAINST?

php - 是否可以为行数重新使用 Kohana ORM 查询?

mongodb - 有什么方法可以在 Azure 中对 MongoDB 进行分析吗?

azure - 如何保护受 APIM 保护的 Azure Functions,以便它们仅响应来自同一资源组中的 Azure Web 应用程序的请求?

ssl - Azure SSL 站点在重启后不再工作 - 连接重置

zend-framework2 - Zend Framework 2 FormElementManager 工厂不工作

php - 如何使用 Zend Framework2 修复此查询

apache - phpinfo() 什么都不输出

php - 按行编辑表格

php - 基于相同关键字显示结果的 SQL 查询