您使用的正確的令牌緩存非常主觀,並且實際上取決於您的架構,性能要求等。
ADAL使用的默認緩存是內存中緩存,這意味着它可能不會在您的API接收的請求之間持續存在。此外,ADAL.NET使用的默認緩存是靜態類,這意味着對您的API的兩個不同請求可能會選取相同的緩存對象,這通常是意料之外的,因爲這兩個請求可能針對不同的用戶。因此,通常不推薦使用默認的ADAL緩存 - 這取決於您的Web服務器的工作方式。
相反,我們建議將null
作爲令牌緩存,如果您可以管理性能命中,或者最好實現您自己的令牌緩存。
如果您想要實現自己的緩存,它將保存您的應用程序不必在每個傳入請求上向AAD發送HTTP請求(通過ADAL)。使用.NET實體框架樣本ADAL緩存實現可here,以下複製以及:
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace TodoListWebApp.DAL
{
public class PerWebUserCache
{
[Key]
public int EntryId { get; set; }
public string webUserUniqueId { get; set; }
public byte[] cacheBits { get; set; }
public DateTime LastWrite { get; set; }
}
public class EFADALTokenCache: TokenCache
{
private TodoListWebAppContext db = new TodoListWebAppContext();
string User;
PerWebUserCache Cache;
// constructor
public EFADALTokenCache(string user)
{
// associate the cache to the current user of the web app
User = user;
this.AfterAccess = AfterAccessNotification;
this.BeforeAccess = BeforeAccessNotification;
this.BeforeWrite = BeforeWriteNotification;
// look up the entry in the DB
Cache = db.PerUserCacheList.FirstOrDefault(c => c.webUserUniqueId == User);
// place the entry in memory
this.Deserialize((Cache == null) ? null : Cache.cacheBits);
}
// clean up the DB
public override void Clear()
{
base.Clear();
foreach (var cacheEntry in db.PerUserCacheList)
db.PerUserCacheList.Remove(cacheEntry);
db.SaveChanges();
}
// Notification raised before ADAL accesses the cache.
// This is your chance to update the in-memory copy from the DB, if the in-memory version is stale
void BeforeAccessNotification(TokenCacheNotificationArgs args)
{
if (Cache == null)
{
// first time access
Cache = db.PerUserCacheList.FirstOrDefault(c => c.webUserUniqueId == User);
}
else
{ // retrieve last write from the DB
var status = from e in db.PerUserCacheList
where (e.webUserUniqueId == User)
select new
{
LastWrite = e.LastWrite
};
// if the in-memory copy is older than the persistent copy
if (status.First().LastWrite > Cache.LastWrite)
//// read from from storage, update in-memory copy
{
Cache = db.PerUserCacheList.FirstOrDefault(c => c.webUserUniqueId == User);
}
}
this.Deserialize((Cache == null) ? null : Cache.cacheBits);
}
// Notification raised after ADAL accessed the cache.
// If the HasStateChanged flag is set, ADAL changed the content of the cache
void AfterAccessNotification(TokenCacheNotificationArgs args)
{
// if state changed
if (this.HasStateChanged)
{
Cache = new PerWebUserCache
{
webUserUniqueId = User,
cacheBits = this.Serialize(),
LastWrite = DateTime.Now
};
//// update the DB and the lastwrite
db.Entry(Cache).State = Cache.EntryId == 0 ? EntityState.Added : EntityState.Modified;
db.SaveChanges();
this.HasStateChanged = false;
}
}
void BeforeWriteNotification(TokenCacheNotificationArgs args)
{
// if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry
}
}
}
只是偶然在此,不是它必要的,你標誌着Clear()方法緩存= null,否則價值永遠不會從變量中移除,然後在BeforeAccess方法中,第一個if不應該被傳遞。因此您也可以獲取錯誤憑證的標記。 –