TheNetworg / oauth2-azure

Azure AD provider for the OAuth 2.0 Client.
https://packagist.org/packages/thenetworg/oauth2-azure
MIT License
230 stars 109 forks source link

Struggling with V2 #83

Closed justechn closed 5 years ago

hajekj commented 5 years ago

What exactly is the issue?

justechn commented 5 years ago

Sorry I hit the enter button too quickly and saved this before I had typed anything. I am typing up the issue, give me just a minute.

justechn commented 5 years ago

I am new to OAuth2, Azure, and Active directory, but I have been asked to work on an integration. After reading this issue https://github.com/TheNetworg/oauth2-azure/issues/82 it seemed like starting with V2 of this library was the best place to start. I am basing most of my code off of the example code in the readme, but either I am doing something terribly wrong or the example is not complete.

So far here is what I have

$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
            'clientId' => 'xxx',
            'clientSecret' => 'xxx',
            'redirectUri' => 'http://localhost/demo',
            'metadata' => 'https://login.microsoftonline.com/xxx.onmicrosoft.com/v2.0/.well-known/openid-configuration',
        ]);

        if (!isset($_GET['code']) || empty($_SESSION['oauth2state'])) {

            // If we don't have an authorization code then get one
            $authUrl = $provider->getAuthorizationUrl([
                'scope' => [
                    'https://graph.windows.net/Directory.AccessAsUser.All',
                    'https://graph.windows.net/Directory.Read.All',
                    'https://graph.windows.net/Directory.ReadWrite.All',
                    'https://graph.windows.net/Group.Read.All',
                    'https://graph.windows.net/Group.ReadWrite.All',
                    'https://graph.windows.net/Member.Read.Hidden',
                    'https://graph.windows.net/User.Read',
                    'https://graph.windows.net/User.Read.All',
                    'https://graph.windows.net/User.ReadBasic.All'
                ]
            ]);
            $_SESSION['oauth2state'] = $provider->getState();
            header('Location: ' . $authUrl);
            exit;

            // Check given state against previously stored one to mitigate CSRF attack
        } else if (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {

            unset($_SESSION['oauth2state']);
            exit('Invalid state');

        } else {

            // Try to get an access token (using the authorization code grant)
            $token = $provider->getAccessToken('authorization_code', [
                'code' => $_GET['code']
            ]);

            // Optional: Now you have a token you can look up a users profile data
            try {

                // We got an access token, let's now get the user's details
                $me = $provider->get("me?api-version=1.6", $token);

                // Use these details to create a new profile
                printf('Hello %s!', $me['givenName']);

            } catch (Exception $e) {

                // Failed to get user details
                echo($e);
                exit('Oh dear...');
            }

            // Use this to interact with an API on the users behalf
            echo $token->getToken();
        }

However I was getting errors from guzzle Could not resolve host: me and after digging in a bit more I found that the host https://graph.windows.net was not being included in the request. So I changed this line $me = $provider->get("me?api-version=1.6", $token); to $me = $provider->get("https://graph.windows.net/me?api-version=1.6", $token); and I seem to get further. However now I am stuck with Cannot use object of type GuzzleHttp\Psr7\Response as array on the line elseif (isset($response['value'])) I have done a var_dump on the response and it looks like this

/var/www/html/vendor/thenetworg/oauth2-azure/src/Provider/Azure.php:179:
object(GuzzleHttp\Psr7\Response)[114]
  private 'reasonPhrase' => string 'OK' (length=2)
  private 'statusCode' => int 200
  private 'headers' => 
    array (size=17)
      'Cache-Control' => 
        array (size=1)
          0 => string 'no-cache' (length=8)
      'Pragma' => 
        array (size=1)
          0 => string 'no-cache' (length=8)
      'Content-Type' => 
        array (size=1)
          0 => string 'application/json; odata=minimalmetadata; streaming=true; charset=utf-8' (length=70)
      'Expires' => 
        array (size=1)
          0 => string '-1' (length=2)
      'ocp-aad-diagnostics-server-name' => 
        array (size=1)
          0 => string 'susOkr8YvnkWhpfwvEOXpfZ/acdphRpz4tl/Fe8Bm3M=' (length=44)
      'request-id' => 
        array (size=1)
          0 => string 'f14277db-1315-40bc-8951-b706eeaebbd3' (length=36)
      'client-request-id' => 
        array (size=1)
          0 => string '4c51b3b7-ad0f-4f65-96fa-7f411b191f9f' (length=36)
      'x-ms-dirapi-data-contract-version' => 
        array (size=1)
          0 => string '1.6' (length=3)
      'ocp-aad-session-key' => 
        array (size=1)
          0 => string 'Wn5GQSp-CA8L4hVNoR7DE3top77w7F0uilW5iga49AUu9Ns1bphTt-j4U25mW3W9TbXjO1QAsVfEPFaQjJcrtTiFpHzBEqwhWwsQK9vMVlJXN088fwWKWJZItL7TsGew.GGYSYACwSWAlTDqNuwTorRruzAaGmy3Mnejp2dQIV6U' (length=172)
      'DataServiceVersion' => 
        array (size=1)
          0 => string '3.0;' (length=4)
      'Strict-Transport-Security' => 
        array (size=1)
          0 => string 'max-age=31536000; includeSubDomains' (length=35)
      'Access-Control-Allow-Origin' => 
        array (size=1)
          0 => string '*' (length=1)
      'X-AspNet-Version' => 
        array (size=1)
          0 => string '4.0.30319' (length=9)
      'X-Powered-By' => 
        array (size=1)
          0 => string 'ASP.NET' (length=7)
      'Duration' => 
        array (size=1)
          0 => string '1154812' (length=7)
      'Date' => 
        array (size=1)
          0 => string 'Wed, 12 Jun 2019 16:04:06 GMT' (length=29)
      'Content-Length' => 
        array (size=1)
          0 => string '1737' (length=4)
  private 'headerNames' => 
    array (size=17)
      'cache-control' => string 'Cache-Control' (length=13)
      'pragma' => string 'Pragma' (length=6)
      'content-type' => string 'Content-Type' (length=12)
      'expires' => string 'Expires' (length=7)
      'ocp-aad-diagnostics-server-name' => string 'ocp-aad-diagnostics-server-name' (length=31)
      'request-id' => string 'request-id' (length=10)
      'client-request-id' => string 'client-request-id' (length=17)
      'x-ms-dirapi-data-contract-version' => string 'x-ms-dirapi-data-contract-version' (length=33)
      'ocp-aad-session-key' => string 'ocp-aad-session-key' (length=19)
      'dataserviceversion' => string 'DataServiceVersion' (length=18)
      'strict-transport-security' => string 'Strict-Transport-Security' (length=25)
      'access-control-allow-origin' => string 'Access-Control-Allow-Origin' (length=27)
      'x-aspnet-version' => string 'X-AspNet-Version' (length=16)
      'x-powered-by' => string 'X-Powered-By' (length=12)
      'duration' => string 'Duration' (length=8)
      'date' => string 'Date' (length=4)
      'content-length' => string 'Content-Length' (length=14)
  private 'protocol' => string '1.1' (length=3)
  private 'stream' => 
    object(GuzzleHttp\Psr7\Stream)[118]
      private 'stream' => resource(14, 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

because this is all new to me I am not sure if this is correct or not. Or if I am using the library incorrectly. I also accept that I may have setup AD in Azure incorrectly. Any tips on where to start would be much appreciated.

hajekj commented 5 years ago

You are on the right path with $me = $provider->get("https://graph.windows.net/me?api-version=1.6", $token); that is correct rather than just me which is v1 library feature.

The issue is that https://github.com/TheNetworg/oauth2-azure/blob/v2.0.0/src/Provider/Azure.php#L232 calls getResponse rather than getParsedResponse. This was fixed in v1 version (https://github.com/TheNetworg/oauth2-azure/pull/32) but didn't make it to V2. If you want, you can create a PR and I will merge it, or if you wait few hours, I think I can get this patched today.

justechn commented 5 years ago

Sweet, that worked. I will work on a PR

justechn commented 5 years ago

I created a PR https://github.com/TheNetworg/oauth2-azure/pull/84

hajekj commented 5 years ago

I merged the PR, thanks for the contirbution!

justechn commented 5 years ago

Awesome, thanks for helping me figure that out. It would be great to get the example in the V2 branch to work out of the box for the V2 microsoft API. For example, adding scope and removing resource, and changing the me line that I had to fix above.