Janilson
Janilson

Reputation: 1183

Implementing TokenCache when I only need to store a single token per cache

I have an app that is meant to read tenant data from multiple tenants which requires admin consent. So I just need to store one access token and one refresh token from AquireTokenByAuthorizationCodeAsync() for each tenant. So I wondered, if I were to implement a TokenCache extension in such a scenario, would it be necessary to implement TokenCache.AfterAccess and TokenCache.BeforeAccess? Also, when using AquireTokenAsync(), are the cachebits getting overwritten by the new tokens aquired or does it just append to it? If I wanted the old tokens to be overwritten, could I simply use TokenCache.BeforeWrite to clear the old cache?

Basically, this is what I had in mind:

public class ADALTokenCache : TokenCache
{
    public Guid TenantId;

    public ADALTokenCache(Guid tenantId) : base()
    {
        TenantId = tenantId;
        using (var dbContext = new MyDbContext())
        {
            byte[] cache = dbContext.TokenCacheSet.FirstOrDefault(c => c.TenantId == TenantId);
            if (cache != null)
            {
                Deserialize(MachineKey.Unprotect(cache, "ADALCache"));
            }
        }
    }


    void BeforeWriteNotification(TokenCacheNotificationArgs args)
    {
        //Could I call Clear() here so that only
        //the new token from AquireTokenAsync() is written?
    }
}

Upvotes: 2

Views: 3701

Answers (1)

Jean-Marc Prieur
Jean-Marc Prieur

Reputation: 1649

To answer your questions

  • The reason why the cache in the samples is as it is, is that several users might sign-in to the application. That will, BTW be the case even if this is the same user in different tenants (the identity might be different). you have examples of implementation in Custom token cache serialization in Web applications / Web API
  • indeed when AcquireTokenSilentAsync will refresh the token it will override the previous token in the cache.

However, stepping back

  • if I understand correctly, in your scenario, your app is not about getting a token to access data for a given user, but rather access tenant data (for the tenant where a user belongs?), and then regularly do some operations.

  • Wouldn't it be more the case that you'd have a daemon application (but multi-tenant) ? and therefore you might want to use a client credentials flow rather than the authorization code flow. Since you are using ADAL (V1 endpoint), you could pre-consent the application in the Azure portal? you would not need to sign-in any user? The page on client credential flows has links to ADAL samples for daemon apps.

  • you might also want to have a look at active-directory-dotnet-daemon-v2 which seems very close to your scenario (but for the Azure AD V2 endpoint). It's easy transposable to the Azure AD V1 endpoint, though, or you could still use the sample as is, but limit the accepted authorities to just a set of tenants.

Upvotes: 4

Related Questions