Skip to content

Commit

Permalink
Merge pull request #98 from microsoft/fix/delegated-token-caching
Browse files Browse the repository at this point in the history
Fix caching access tokens for delegated permissions
  • Loading branch information
Ndiritu authored Nov 14, 2024
2 parents 5be0ae1 + 82551bc commit 9902a1e
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/Oauth/ApplicationPermissionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ abstract public function getTenantId(): string;

/**
* Set the identity of the user/application. This is used as the unique cache key
* For delegated permissions the key is {tenantId}-{clientId}-{userId}
* For delegated permissions the key is {tenantId}-{clientId}-{accessTokenHash}
* For application permissions, they key is {tenantId}-{clientId}
* @param AccessToken|null $accessToken
* @return void
Expand All @@ -44,7 +44,7 @@ public function setCacheKey(?AccessToken $accessToken = null): void

/**
* Return the identity of the user/application. This is used as the unique cache key
* For delegated permissions the key is {tenantId}-{clientId}-{userId}
* For delegated permissions the key is {tenantId}-{clientId}-{accessTokenHash}
* For application permissions, they key is {tenantId}-{clientId}
* @return string|null
*/
Expand Down
15 changes: 4 additions & 11 deletions src/Oauth/DelegatedPermissionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

use League\OAuth2\Client\Token\AccessToken;


trait DelegatedPermissionTrait
{
use CAEConfigurationTrait;
Expand All @@ -33,28 +32,22 @@ abstract public function getTenantId(): string;

/**
* Set the identity of the user/application. This is used as the unique cache key
* For delegated permissions the key is {tenantId}-{clientId}-{userId}
* For delegated permissions the key is {tenantId}-{clientId}-{accessTokenHash}
* For application permissions, they key is {tenantId}-{clientId}
* @param AccessToken|null $accessToken
* @return void
*/
public function setCacheKey(?AccessToken $accessToken = null): void
{
if ($accessToken && $accessToken->getToken()) {
$tokenParts = explode('.', $accessToken->getToken());
if (count($tokenParts) == 3) {
$payload = json_decode(base64_decode($tokenParts[1]), true);
if (is_array($payload) && array_key_exists('sub', $payload)) {
$subject = $payload['sub'];
$this->cacheKey = ($subject) ? "{$this->getTenantId()}-{$this->getClientId()}-{$subject}" : null;
}
}
$uniqueIdentifier = password_hash($accessToken->getToken(), PASSWORD_DEFAULT);
$this->cacheKey = "{$this->getTenantId()}-{$this->getClientId()}-{$uniqueIdentifier}";
}
}

/**
* Return the identity of the user/application. This is used as the unique cache key
* For delegated permissions the key is {tenantId}-{clientId}-{userId}
* For delegated permissions the key is {tenantId}-{clientId}-{accessTokenHash}
* For application permissions, they key is {tenantId}-{clientId}
* @return string|null
*/
Expand Down
4 changes: 2 additions & 2 deletions src/Oauth/TokenRequestContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function getTenantId(): string;

/**
* Set the identity of the user/application. This is used as the unique cache key
* For delegated permissions the key is {tenantId}-{clientId}-{userId}
* For delegated permissions the key is {tenantId}-{clientId}-{accessTokenHash}
* For application permissions, they key is {tenantId}-{clientId}
* @param AccessToken|null $accessToken
* @return void
Expand All @@ -57,7 +57,7 @@ public function setCacheKey(?AccessToken $accessToken = null): void;

/**
* Return the identity of the user/application. This is used as the unique cache key
* For delegated permissions the key is {tenantId}-{clientId}-{userId}
* For delegated permissions the key is {tenantId}-{clientId}-{accessTokenHash}
* For application permissions, they key is {tenantId}-{clientId}
*
* @return string|null
Expand Down
12 changes: 12 additions & 0 deletions tests/Cache/InMemoryAccessTokenCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use League\OAuth2\Client\Token\AccessToken;
use Microsoft\Kiota\Authentication\Cache\InMemoryAccessTokenCache;
use Microsoft\Kiota\Authentication\Oauth\AuthorizationCodeContext;
use Microsoft\Kiota\Authentication\Oauth\ClientCredentialContext;
use Microsoft\Kiota\Authentication\Oauth\TokenRequestContext;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -58,4 +59,15 @@ public function testWithTokenAddsMultipleTokensToCache() {
$this->assertInstanceOf(AccessToken::class, $cache->getTokenWithContext($this->testTokenRequestContext));
$this->assertInstanceOf(AccessToken::class, $cache->getTokenWithContext($secondContext));
}

public function testCacheKeyIsSetForNonJWTToken() {
$accessToken = $this->createMock(AccessToken::class);
$accessToken->method('getToken')->willReturn('token');

$cache = new InMemoryAccessTokenCache();
$delegatedTokenRequestContext = new AuthorizationCodeContext("tenantId", "clientId", "clientSecret", "redirectUri", "code");
$cache->withToken($delegatedTokenRequestContext, $accessToken);

$this->assertNotEmpty($delegatedTokenRequestContext->getCacheKey());
}
}

0 comments on commit 9902a1e

Please sign in to comment.