当我只需要为每个缓存存储一个令牌时实现 TokenCache
Implementing TokenCache when I only need to store a single token per cache
我有一个应用程序需要管理员同意才能从多个租户读取租户数据。所以我只需要为每个租户存储来自 AquireTokenByAuthorizationCodeAsync()
的一个访问令牌和一个刷新令牌。所以我想,如果我在这种场景下实现一个TokenCache扩展,是否有必要实现TokenCache.AfterAccess
和TokenCache.BeforeAccess
?此外,当使用 AquireTokenAsync()
时,缓存位是否会被获取的新令牌覆盖,还是只是附加到它?如果我想覆盖旧令牌,我可以简单地使用 TokenCache.BeforeWrite
清除旧缓存吗?
基本上,这就是我的想法:
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?
}
}
回答您的问题
- 示例中的缓存之所以保持原样,是因为多个用户可能会登录到该应用程序。顺便说一句,即使这是不同租户中的同一用户(身份可能不同)也是如此。您在 中有实施示例
Web 应用程序/Web 中的自定义令牌缓存序列化 API
- 确实,当
AcquireTokenSilentAsync
刷新令牌时,它将覆盖缓存中的先前令牌。
不过,退一步
如果我没理解错的话,在你的场景中,你的应用不是获取令牌来访问给定用户的数据,而是访问租户数据(对于用户所属的租户?) ,然后定期做一些操作。
如果您有一个守护程序应用程序(但多租户),情况会不会更好?因此您可能想要使用 client credentials flow rather than the authorization code flow。
由于您使用的是 ADAL(V1 终结点),您可以在 Azure 门户中预先同意该应用程序吗?您不需要登录任何用户?客户端凭据流页面包含指向守护程序应用程序的 ADAL 示例的链接。
您可能还想看看 active-directory-dotnet-daemon-v2,它看起来非常接近您的场景(但对于 Azure AD V2 端点)。不过,它很容易转移到 Azure AD V1 端点,或者您仍然可以按原样使用示例,但将接受的权限限制为仅一组租户。
我有一个应用程序需要管理员同意才能从多个租户读取租户数据。所以我只需要为每个租户存储来自 AquireTokenByAuthorizationCodeAsync()
的一个访问令牌和一个刷新令牌。所以我想,如果我在这种场景下实现一个TokenCache扩展,是否有必要实现TokenCache.AfterAccess
和TokenCache.BeforeAccess
?此外,当使用 AquireTokenAsync()
时,缓存位是否会被获取的新令牌覆盖,还是只是附加到它?如果我想覆盖旧令牌,我可以简单地使用 TokenCache.BeforeWrite
清除旧缓存吗?
基本上,这就是我的想法:
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?
}
}
回答您的问题
- 示例中的缓存之所以保持原样,是因为多个用户可能会登录到该应用程序。顺便说一句,即使这是不同租户中的同一用户(身份可能不同)也是如此。您在 中有实施示例 Web 应用程序/Web 中的自定义令牌缓存序列化 API
- 确实,当
AcquireTokenSilentAsync
刷新令牌时,它将覆盖缓存中的先前令牌。
不过,退一步
如果我没理解错的话,在你的场景中,你的应用不是获取令牌来访问给定用户的数据,而是访问租户数据(对于用户所属的租户?) ,然后定期做一些操作。
如果您有一个守护程序应用程序(但多租户),情况会不会更好?因此您可能想要使用 client credentials flow rather than the authorization code flow。 由于您使用的是 ADAL(V1 终结点),您可以在 Azure 门户中预先同意该应用程序吗?您不需要登录任何用户?客户端凭据流页面包含指向守护程序应用程序的 ADAL 示例的链接。
您可能还想看看 active-directory-dotnet-daemon-v2,它看起来非常接近您的场景(但对于 Azure AD V2 端点)。不过,它很容易转移到 Azure AD V1 端点,或者您仍然可以按原样使用示例,但将接受的权限限制为仅一组租户。