public void Load() { // look up the entry in the cache var cache = Redis.Connection.GetDatabase(); try { var cachedItem = cache.StringGet(cacheId); if (cachedItem.HasValue) { this.Cache = JsonConvert.DeserializeObject <UserTokenCacheItem>(cachedItem); // ToDo: if the entry in Redis cache is older than 1 hour which is the default validity of AAD access token then kill it. //var purpose = GetMachineKeyPurpose(Thread.CurrentPrincipal); var purpose = GetMachineKeyPurpose(); //this.Deserialize((this.Cache == null) ? null : MachineKey.Unprotect(this.Cache.cacheBits, purpose)); //this.Deserialize((this.Cache == null) ? null : AesEncryptionHelper.Decrypt(this.Cache.cacheBits, purpose)); AesManagedCryptoLib _crypt = new AesManagedCryptoLib(); //this.Deserialize((this.Cache == null) ? null : _crypt.decrypt(this.Cache.CacheBits, purpose, localVector)); this.Deserialize((this.Cache == null) ? null : _crypt.decrypt(this.Cache.CacheBits, purpose, this.Cache.InitializationVector)); } } catch (Exception ex) { Trace.WriteLine("Exception in RedisTokenCache(id): " + ex.Message); Cache = null; } }
// Notification raised before ADAL accesses the cache. // This is your chance to update the in-memory copy from the cache, if the in-memory version is stale void BeforeAccessNotification(TokenCacheNotificationArgs args) { try { var cache = Redis.Connection.GetDatabase(); var cachedItem = cache.StringGet(cacheId); if (cachedItem.HasValue) { var status = JsonConvert.DeserializeObject <UserTokenCacheItem>(cachedItem); if ((this.Cache != null) && (status.LastWrite > this.Cache.LastWrite)) { this.Cache = status; //var purpose = GetMachineKeyPurpose(Thread.CurrentPrincipal); var purpose = GetMachineKeyPurpose(); //this.Deserialize((Cache == null) ? null : MachineKey.Unprotect(Cache.cacheBits, purpose)); //this.Deserialize((Cache == null) ? null : AesEncryptionHelper.Decrypt(Cache.cacheBits, purpose)); AesManagedCryptoLib _crypt = new AesManagedCryptoLib(); //this.Deserialize((this.Cache == null) ? null : _crypt.decrypt(this.Cache.CacheBits, purpose, localVector)); this.Deserialize((this.Cache == null) ? null : _crypt.decrypt(this.Cache.CacheBits, purpose, this.Cache.InitializationVector)); } } } catch (Exception ex) { Trace.WriteLine("Exception in RedisTokenCache.BeforeAccessNotification: " + ex.Message); } }
// 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) { //var purpose = GetMachineKeyPurpose(Thread.CurrentPrincipal); var purpose = GetMachineKeyPurpose(); AesManagedCryptoLib _crypt = new AesManagedCryptoLib(); string dynamicVector = AesManagedCryptoLib.GenerateRandomIV(16); //16 bytes = 128 bits Cache = new UserTokenCacheItem { //cacheBits = MachineKey.Protect(this.Serialize(), purpose), //cacheBits = AesEncryptionHelper.Encrypt(this.Serialize(), purpose), //cacheBits = cryptoHelper.Encrypt(this.Serialize()), //CacheBits = _crypt.encrypt(this.Serialize(), purpose, localVector), CacheBits = _crypt.encrypt(this.Serialize(), purpose, dynamicVector), InitializationVector = dynamicVector, LastWrite = DateTime.Now.ToUniversalTime() }; try { var cache = Redis.Connection.GetDatabase(); var cacheItemJson = JsonConvert.SerializeObject(Cache); cache.StringSet(cacheId, cacheItemJson, TimeSpan.FromDays(1)); // could we use token expiry somehow? } catch (Exception ex) { Trace.WriteLine("Exception in RedisTokenCache.AfterAccessNotification: " + ex.Message); } this.HasStateChanged = false; } }