Invalid_grant error when calling GraphServiceClient

Nicolae Gaidarji 0 Reputation points
2024-06-13T16:34:11.9266667+00:00

Hi, I am using AuthorizationCodeContext authentication to get token to GraphServiceClient service.

authorization is done via https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id={client_id}&response_type=code&redirect_uri={redirect_uri}&response_mode=query&scope={scopes}&state=12345

I get the following error:

Error: League\OAuth2\Client\Provider\Exception\IdentityProviderException: invalid_grant in /home/unisimso/api.unisim-soft.com/AZURE/vendor/league/oauth2-client/src/Provider/GenericProvider.php:236
Stack trace:
#0 /home/unisimso/api.unisim-soft.com/AZURE/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(726): League\OAuth2\Client\Provider\GenericProvider->checkResponse(Object(GuzzleHttp\Psr7\Response), Array)
#1 /home/unisimso/api.unisim-soft.com/AZURE/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(635): League\OAuth2\Client\Provider\AbstractProvider->getParsedResponse(Object(GuzzleHttp\Psr7\Request))
#2 /home/unisimso/api.unisim-soft.com/AZURE/vendor/microsoft/kiota-authentication-phpleague/src/PhpLeagueAccessTokenProvider.php(303): League\OAuth2\Client\Provider\AbstractProvider->getAccessToken(Object(League\OAuth2\Client\Grant\AuthorizationCode), Array)
#3 /home/unisimso/api.unisim-soft.com/AZURE/vendor/microsoft/kiota-authentication-phpleague/src/PhpLeagueAccessTokenProvider.php(169): Microsoft\Kiota\Authentication\PhpLeagueAccessTokenProvider->requestNewToken(Array, Object(OpenTelemetry\API\Trace\NonRecordingSpan))
#4 /home/unisimso/api.unisim-soft.com/AZURE/vendor/microsoft/kiota-abstractions/src/Authentication/BaseBearerTokenAuthenticationProvider.php(75): Microsoft\Kiota\Authentication\PhpLeagueAccessTokenProvider->getAuthorizationTokenAsync('https://graph.m...', Array)
#5 /home/unisimso/api.unisim-soft.com/AZURE/vendor/microsoft/kiota-http-guzzle/src/GuzzleRequestAdapter.php(541): Microsoft\Kiota\Abstractions\Authentication\BaseBearerTokenAuthenticationProvider->authenticateRequest(Object(Microsoft\Kiota\Abstractions\RequestInformation), Array)
#6 /home/unisimso/api.unisim-soft.com/AZURE/vendor/microsoft/kiota-http-guzzle/src/GuzzleRequestAdapter.php(144): Microsoft\Kiota\Http\GuzzleRequestAdapter->getHttpResponseMessage(Object(Microsoft\Kiota\Abstractions\RequestInformation), '', Object(OpenTelemetry\API\Trace\NonRecordingSpan))
#7 /home/unisimso/api.unisim-soft.com/AZURE/vendor/microsoft/microsoft-graph/src/Generated/Users/UsersRequestBuilder.php(98): Microsoft\Kiota\Http\GuzzleRequestAdapter->sendAsync(Object(Microsoft\Kiota\Abstractions\RequestInformation), Array, Array)
#8 /home/unisimso/api.unisim-soft.com/AZURE/callback.php(43): Microsoft\Graph\Generated\Users\UsersRequestBuilder->get()
#9 {main}

can someone help me


function getAccessToken($tenantId, $clientId, $clientSecret, $redirectUri, $authCode) {
    $url = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token";
    $headers = [
        'Content-Type: application/x-www-form-urlencoded'
    ];
    $postFields = [
        'client_id' => $clientId,
        'scope' => 'https://graph.microsoft.com/User.Read',
        'code' => $authCode,
        'redirect_uri' => $redirectUri,
        'grant_type' => 'authorization_code',
        'client_secret' => $clientSecret
    ];

    $client = new Client();
    $response = $client->post($url, [
        'headers' => $headers,
        'form_params' => $postFields
    ]);

    if ($response->getStatusCode() !== 200) {
        throw new Exception('Failed to get access token');
    }

    $body = json_decode((string)$response->getBody(), true);
    print_r($body);
    if (isset($body['access_token'])) {
        return $body['access_token'];
    } else {
        throw new Exception('Failed to get access token: ' . $body['error_description']);
    }
}


//----------------------------
$token = getAccessToken($tenantId, $clientId, $clientSecret, $redirectUri, $authCode);

$tokenContext = new AuthorizationCodeContext(
    $tenantId,
    $clientId,
    $clientSecret,
    $token,
    $redirectUri);


$graphServiceClient = new GraphServiceClient($tokenContext, $scopes);

$result = $graphServiceClient->users()->get()->wait();
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
21,792 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Raja Pothuraju 6,445 Reputation points Microsoft Vendor
    2024-06-17T07:14:26.2066667+00:00

    Hello @Nicolae Gaidarji,

    Thank you for posting your query on Microsoft Q&A.

    Based on the script you shared, it appears you are attempting to generate an access token using a client_secret via OAuth 2.0 authorization code flow.

    I noticed that you have successfully generated an authorization code using the correct flow: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id={client_id}&response_type=code&redirect_uri={redirect_uri}&response_mode=query&scope={scopes}&state=12345.

    Next, you need to use this code to redeem an access token with a client_secret. However, you encountered an error message indicating "invalid_grant."

    This type of error message typically occurs when the authorization code has expired. Authorization codes are short-lived and generally expire after about 10 minutes.

    May I know here, the code that you used to get an access token isn't expired? Once you generate a code you have to be utilize within 10 minutes of time frame.

    If the code as expired the recommended action is to make a new request to the /authorize endpoint and verify that the code_verifier parameter was correct.

    Please let me know if that resolves your issue or not. If not, please share more details about the error message from Microsoft Entra sign-in logs.

    Thank you for your cooperation, and I look forward to resolving this issue.

    Hope this includes all the information that you were looking for.

    Please "Accept the answer" if the information helped you. This will help us and others in the community as well.

    Thanks,
    Raja Pothuraju.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.