microsoftgraph / microsoftgraph/msgraph-sdk-php
access_token from OAuth login: already redeemed
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- PHP
- Estrellas
- 669
- Forks
- 150
- Merge medio
- 15 h 21 min
- PR fusionados (30 d)
- 3
Descripción
Hello everyone!
I've successfully implemented a proof of concept for an application with Authorization Code Flow.
Calling the code below by browser, shows expected informations, BUT when one reloads the "page" a
"IdentityProviderException" with message "invalid_grant" occures - wich is really missleading IMHO.
Digging deeper one finds this "error_description":
"AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code ..."
The code below (as a proof of concept) is part of a SaaS application and should handle different taks.
In this sceanario above exception is thrown from second try to use the script.
As you can see, the "access_token" is not used directly but it seems the SDK uses it internally.
Is there a clean implementation to avoid such exceptions?
I have already a "brute force solution" by redirecting all new calls to the script
to 'https://login.microsoftonline.com/'.TENANT_ID.'/oauth2/v2.0/authorize'
but this realy, realy ugly and far from a clean solution I think.
What is wrong with this code or is this a "misbehavior" of SDK?
const TENANT_ID = '...';
const CLIENT_ID = '...';
const SECRET = '...';
const REDIRECT_TO_URI = 'https://example.com/GraphApplicationTest.php'; // placeholder!!
const MS_AUTHORIZE_URI = 'https://login.microsoftonline.com/'.TENANT_ID.'/oauth2/v2.0/authorize';
const MS_TOKEN_URI = 'https://login.microsoftonline.com/'.TENANT_ID.'/oauth2/v2.0/token';
const MS_RESSOURCE_URI = 'https://login.microsoftonline.com/'.TENANT_ID;
$basicScopes = [ 'https://graph.microsoft.com/.default' ];
$extendedScopes = [
'openid',
'offline_access',
'User.Read',
'User.Read.All',
'User.ReadBasic.All',
];
$oauthGenProvider = NULL;
$authCode = "";
$accessToken = NULL;
$nextToken = NULL;
$tokenContext = NULL;
$oauthGenProvider = new GenericProvider([
'clientId' => CLIENT_ID,
'clientSecret' => SECRET,
'redirectUri' => REDIRECT_TO_URI,
'urlAuthorize' => MS_AUTHORIZE_URI,
'urlAccessToken' => MS_TOKEN_URI,
'urlResourceOwnerDetails' => MS_RESSOURCE_URI,
'scopes' => $basicScopes,
],
);
// check errors from eventually previous request
if ( isset( $_GET['error'] ) )
{
echo "<pre>";
echo "exiting with error!\n\n";
echo "error: ".$_GET['error']."\n";
echo "description:\n ".$_GET['error_description']."\n";
exit;
}
// if not authenticated goto "login"
if (!isset($_GET['code']))
{
$authorizationUrl = $oauthGenProvider->getAuthorizationUrl();
header('Location: ' . $authorizationUrl);
exit;
}
echo "<pre>";
echo "SDK version is ".GraphConstants::SDK_VERSION."\n";
$authCode = $_GET['code'];
// first step to prepare for "GraphServiceClient": create a context of type "AuthorizationCodeContext"
// Microsoft\Kiota\Authentication\Oauth\AuthorizationCodeContext
// https://github.com/microsoft/kiota-authentication-phpleague-php/blob/main/src/Oauth/AuthorizationCodeContext.php
$tokenContext = new AuthorizationCodeContext(
TENANT_ID,
CLIENT_ID,
SECRET,
$authCode,
REDIRECT_TO_URI,
);
$graphClient = new GraphServiceClient($tokenContext, $extendedScopes);
try
{
$users = $graphClient->users()->get()->wait();
$userList = $users->getValue(); // returns an array!
// $userList[x] <==> Microsoft\Graph\Generated\Models\User
// https://github.com/microsoftgraph/msgraph-sdk-php/blob/main/src/Generated/Models/User.php
echo " user[0] display name: ".$userList[0]->getDisplayName()."\n";
}
catch ( Exception $e )
{
if ( $e instanceof \League\OAuth2\Client\Provider\Exception\IdentityProviderException )
{
echo " IdentityProviderException\n";
echo $e->getResponseBody()["error_description"];
// AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.
}
else
{
echo " Exception";
}
echo $e->getMessage()."\n";
}
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza revisando el flujo OAuth alrededor de GenericProvider, AuthorizationCodeContext y GraphServiceClient; después, reproduce el fallo recargando la URL de callback. Compara la primera y la segunda solicitud y determina si el SDK debería gestionar de otra manera el código de autorización canjeado; la finalización debe incluir un comportamiento esperado claro o un procedimiento de uso documentado.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- php
- Área
- api, authentication
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Necesita aclaración
- Aptitud para principiantes
- 25/100