TheNetworg / oauth2-azure

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

Cannot run Graph API query after logging in #169

Closed tip2tail closed 1 year ago

tip2tail commented 1 year ago

Hello

I have setup authentication for users to login to my app, and this is working. Users can login are are generated a token. Decoding a token for my user session on https://jwt.ms/ shows me that the token has my user account details and scopes as:

"scp": "Directory.Read.All email openid profile User.Read User.Read.All",

The app setup in Azure AD has been configured by my IT colleagues as having these permissions "Delegated". Additionally, Directory.Read.All and User.Read.All are grated as "Application". Admin authority has been given.

However, when I then try to make any requests to the Graph API I get the following HTTP 401:

Access token validation failure. Invalid audience.

My code looks like this:

// This is the token that was stored as part of the authentication flow and then stored on the session
// $accessToken = $this->fetchAccessToken($client);
// $request->getSession()->set('azure.access.token', $accessToken);
$token = $request->getSession()->get('azure.access.token', '');

$graph = new Graph();
$graph->setAccessToken($token);
$result = $graph
                ->createRequest('GET', '/me')
                ->execute();

I am unsure what more I need to do to get this to work, I feel I may be missing a stage in the process flow but any help appreciated!

decomplexity commented 1 year ago

In your JWT, what is the claim's 'aud' value ?

tip2tail commented 1 year ago

@decomplexity

"aud": "https://graph.windows.net/",

Does this help?

tip2tail commented 1 year ago

And yes... yes it does help!

It made me look at why you might ask that, and whether that is wrong.

I identified that I need to exchange my "login" token for a "graph" token:

// Swap our login token for a graph token
/** @var Azure $provider */
$provider = $client->getOAuth2Provider();
$provider->urlAPI = 'https://graph.microsoft.com';
$provider->resource = 'https://graph.microsoft.com/';
$graphToken = $provider->getAccessToken('refresh_token', [
    'refresh_token' => $accessToken->getRefreshToken(),
    'resource' => 'https://graph.microsoft.com'
]);

I then use the graph token on the graph request - and boom! Got the data I need.

Thank you @decomplexity for the prompt.

decomplexity commented 1 year ago

Hmm.... graph.windows.net is the older AAD Graph library. You could try using the MSAL library endpoint graph.microsoft.com. The Access token AUD has to be identical to the resource API's address or the API will bounce authorization (unless MSFT has somehow aliased the two). The AUD need not 'look' identical since it may be in the form of a client ID, URI or a 128-bit GUID (the V1 AAD could also be a resource ID) but all refer to the same thing