0

I have this Zend 2 application where I'm making use of this Azure AD library for authentication. Everything has been working fine for a few months, but all of a sudden it stopped working on my localhost. The strange part is that it still works fine on our server. I don't believe this is an issue with the library itself, which is why I'm asking for help here as well.

Whenever I try to get the Provider for oauth2 using the following code:
(This Azure class is simply an extention of 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;
}

I get the following error:

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}

I have searched online for a full day at this point, but I can't seem to find any concrete solutions to this issue. Does anyone have an idea of what might be going on?

If I manually perform a curl command and go to https://login.microsoftonline.com it seems to work fine. My cURL versions both on localhost and on server are 7.64.0, so there's no difference between the two. If I should provide some more info then let me know!

Edit: More of my source code is below:

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

2 Answers2

1

The error reads:

Could not resolve host: login.microsoftonline.com

As you said the application was working fine few months ago then, I think it will work fine if you clear all type of caches in Artisan. Run these following commands together and then restart your server again.

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

Try changing the code you used to initializes the oauth provider for Azure AAD. The following code snippet shows how you can do that.

$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;

And now you can now retrieve the access token with the following code.

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

You should read this Accessing AAD OAuth2 protected API from PHP document for more information.

SauravDas-MT
  • 1,224
  • 1
  • 4
  • 10
  • Thank you for the suggestion. Unfortunately we do not make use of artisan, so I cannot make use of those commands. I have tried the tutorial in the document you provided, but I believe said tutorial does not align with our purposes; we aren't trying to do a call to an API with an access token, we merely want users to log in to our application using Azure. So I do not believe I can use the different strategy with using `urlAPI` and `client_credentials`. I will edit my original post to show more of our code, maybe that will help :) – UltraZethos Nov 04 '21 at 08:52
1

It has been solved. We had pinpointed the issue to having something to do with the Docker DNS settings, but couldn't figure out what was needed exactly. After updating docker to the latest updates, the error was gone.

I'm assuming the issue was within docker itself then. Thank you for the help, in any case!