TheNetworg / oauth2-azure

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

Client error: GET https://graph.microsoft.com/v1.0/me resulted in a `401 Unauthorized` response - InvalidAuthenticationToken - Access token validation failure #87

Closed Sam-digitalife closed 5 years ago

Sam-digitalife commented 5 years ago

Hi all, Since few days I try to use the token received with Oauth2-Client with MSGraph but till now I always get the same issue. 401 unauthorized. I'm able to get the token and query azure AD to get user details. but when I give the token to MSGraph I always get 401 Unauthorized :-/ Any idea ?

// Set up a new Oauth2 client that will be talking to Azure $provider = new TheNetworg\OAuth2\Client\Provider\Azure([ 'clientId' => CLIENT_ID, 'clientSecret' => CLIENT_SECRET, 'redirectUri' => REDIRECT_URI, ]);

if (!isset($_GET['code'])) {

// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->getState();
header('Location: '.$authUrl);
exit;

// Check given state against previously stored one to mitigate CSRF attack } elseif (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'],
    'resource' => 'https://graph.microsoft.com',
    'urlAPI' => 'https://graph.microsoft.com/v1.0/',
]);
echo '<br>Token: '.$token.'!<br>';
// Use this to interact with an API on the users behalf
//echo $token->getToken();

// 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", $token);

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

    $resourceOwner = $provider->getResourceOwner($token);
    echo '<br>Tenant: '.$resourceOwner->getTenantId().'!<br>';

    $graph = new Graph();
    $graph
  ->setBaseUrl("https://graph.microsoft.com/")
  ->setApiVersion("v1.0")
  ->setAccessToken($token);

    $user = $graph->createRequest("get", "/me")
            ->addHeaders(array("Content-Type" => "application/json"))
            ->setReturnType(Model\User::class)
            ->setTimeout("1000")
            ->execute();  

} catch (Exception $e) {

    //Failed to get user details
    echo 'Caught exception: ',  $e->getMessage(), "\n";
    exit('<br>Oh dear...');
}

}

hajekj commented 5 years ago

Hey, what is the message that is accompanying the 401? Can you maybe dump the error message and post it here.


From: Sam-digitalife notifications@github.com Sent: Friday, June 28, 2019 3:50:30 PM To: TheNetworg/oauth2-azure Cc: Subscribed Subject: [TheNetworg/oauth2-azure] Client error: GET https://graph.microsoft.com/v1.0/me resulted in a 401 Unauthorized response - InvalidAuthenticationToken - Access token validation failure (#87)

Hi all, Since few days I try to use the token received with Oauth2-Client with MSGraph but till now I always get the same issue. 401 unauthorized. I'm able to get the token and query azure AD to get user details. but when I give the token to MSGraph I always get 401 Unauthorized :-/ Any idea ?

// Set up a new Oauth2 client that will be talking to Azure $provider = new TheNetworg\OAuth2\Client\Provider\Azure([ 'clientId' => CLIENT_ID, 'clientSecret' => CLIENT_SECRET, 'redirectUri' => REDIRECT_URI, ]);

if (!isset($_GET['code'])) {

// If we don't have an authorization code then get one $authUrl = $provider->getAuthorizationUrl(); $_SESSION['oauth2state'] = $provider->getState(); header('Location: '.$authUrl); exit;

// Check given state against previously stored one to mitigate CSRF attack } elseif (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'], 'resource' => 'https://graph.microsoft.com', 'urlAPI' => 'https://graph.microsoft.com/v1.0/', ]); echo '
Token: '.$token.'!
'; // Use this to interact with an API on the users behalf //echo $token->getToken();

// 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", $token);

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

$resourceOwner = $provider->getResourceOwner($token);
echo '<br>Tenant: '.$resourceOwner->getTenantId().'!<br>';

$graph = new Graph();
$graph

->setBaseUrl("https://graph.microsoft.com/") ->setApiVersion("v1.0") ->setAccessToken($token);

$user = $graph->createRequest("get", "/me")
                ->addHeaders(array("Content-Type" => "application/json"))
                ->setReturnType(Model\User::class)
                ->setTimeout("1000")
                ->execute();

} catch (Exception $e) {

//Failed to get user details
echo 'Caught exception: ',  $e->getMessage(), "\n";
exit('<br>Oh dear...');

}

}

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FTheNetworg%2Foauth2-azure%2Fissues%2F87%3Femail_source%3Dnotifications%26email_token%3DAB7TT6OIT4V7HD2E56BRJSLP4YJKNA5CNFSM4H4FRPO2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4G4KH36Q&data=02%7C01%7Cjan.hajek%40thenetw.org%7C100642b5679d4201eae408d6fbcf9633%7C67266d438de7494d9ed83d1bd3b3a764%7C1%7C0%7C636973266342806302&sdata=Bf2Z4s0yvMKDYyuoZ8BCziLSN72VSEkXuo3fVRMAybU%3D&reserved=0, or mute the threadhttps://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAB7TT6M23FVFYPNQW2PNKZDP4YJKNANCNFSM4H4FRPOQ&data=02%7C01%7Cjan.hajek%40thenetw.org%7C100642b5679d4201eae408d6fbcf9633%7C67266d438de7494d9ed83d1bd3b3a764%7C1%7C0%7C636973266342816311&sdata=59YiN13fZiI3a%2F49qtMEc3ykD100N2ro0dMbgs56LFw%3D&reserved=0.

Sam-digitalife commented 5 years ago

Hi, Thx for your follow-up. This is the message I got: Client error: GET https://graph.microsoft.com/v1.0/me resulted in a 401 Unauthorized response: { "error": { "code": "InvalidAuthenticationToken", "message": "Access token validation failure. Invalid aud (truncated...)

The error only appears when I try to use the Graph object. Before I get well the token, the user name & the tenant id

hajekj commented 5 years ago

Could you please take the token and post the claims here (only the claims, not the token). You can use https://jwt.io to parse the token into JSON claims. Since it says Invalid aud I would suspect there is something wrong with the token.

Sam-digitalife commented 5 years ago

I just copied the token on jwt.io, which part do you want exactly ? I have 3 parts (header, payload & signature) ? at the bottom it said "invalid signature". But which is strange, I got the token, I can get the user and the tenant. But as soon as I use the token with a graph object then...

hajekj commented 5 years ago

Just the payload. Feel free to remove the username from there and any PII data. The invalid signature there is okay, because you didn't specify the certificate to check the signature against.

hajekj commented 5 years ago

Actually, I just noticed what is wrong:

You are obtaining a token for default Azure AD Graph (https://graph.windows.net), but you need to specify that you want to use Microsoft Graph as per https://github.com/TheNetworg/oauth2-azure#microsoft-graph:

$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
'clientId' => CLIENT_ID,
'clientSecret' => CLIENT_SECRET,
'redirectUri' => REDIRECT_URI,
]);
$provider->resource = "https://graph.microsoft.com/";
$provider->urlAPI = "https://graph.microsoft.com/v1.0/";
Sam-digitalife commented 5 years ago

Indeed it's graph.windows.net, but I don't know where I have to adapt it Payload:

"aud": "https://graph.windows.net/", "iss": "https://sts.windows.net/56f59d70-9c12-4cb5-bdba-995548fc796e/", "iat": 1561752684, "nbf": 1561752684, "exp": 1561756584, "acr": "1", "aio": "42ZgYGC7N9nS01zf7b172qvr3Wrex/13q84PyvH+Oen71lUSZ7MB", "amr": [ "pwd" ], "appid": "7533d0bc-3abd-466c-9b5f-d094ee79aa4e", "appidacr": "1", "family_name": "xxx", "given_name": "xxx", "ipaddr": "xxx", "name": "xxx", "oid": "c0c3a957-22dc-4ec5-bf2b-bad2392bbbf9", "puid": "100320003F6F712C", "scp": "Bookings.Manage.All Bookings.Read.All Bookings.ReadWrite.All BookingsAppointment.ReadWrite.All Calendars.Read Calendars.Read.Shared Calendars.ReadWrite Calendars.ReadWrite.Shared email offlineaccess openid profile User.Read", "sub": "EZaiO-xh4bgpMBUp8APHywOfnAPm359OLXOtJA4zVk", "tenant_region_scope": "EU", "tid": "56f59d70-9c12-4cb5-bdba-995548fc796e", "unique_name": "xxx", "upn": "xxx", "uti": "mHA2ewlfPE-4XOUklp6LAA", "ver": "1.0" }

Sam-digitalife commented 5 years ago

Sounds ok now. I don't get issue anymore. Now I have to start using Graph object. Thanks a lot for your help. I close the ticket