Caching IPrincipal With IsolatedStorageBackingStore

Topics: Security Application Block
Mar 2, 2011 at 6:18 AM
Edited Mar 2, 2011 at 6:35 AM

Hi All, 

I am using Enterprise Library Version 5.0.414 having trouble with caching IPrincipal to IsolatedStorageBackingStore to be used across application lifetime - apart from whether this is a good practice (although I welcome any suggestions on this). I have no problem storing and retrieving IPrincipal object within single application lifetime, but when I shutdown and re-run the application it failed in retrieving the IPrincipal stored in previous run. By debugging ISecurityCacheProvider I can tell that the entry was still there (I found the entry with the token obtained previously), however there was no IPrincipal object attached to it. 

I then tried to debug the Security Application Block source code and found the following, which I suspected my be a coding defect:

The following snippet shows the implementation of SavePrincipal() method of CachingStoreProvider class:

public override void SavePrincipal(IPrincipal principal, IToken token)
{
      GetSecurityCacheItem(token, true).Principal = principal;
}

The second parameter of the call to GetSecurityCacheItem() instructs the method to create new instance of SecurityCacheItem class when it is not found in the cache as shown in the next code snippet below:

private SecurityCacheItem GetSecurityCacheItem(IToken token, bool createIfNull)
{
      SecurityCacheItem item = null;
      item = securityCacheManager.GetData(token.Value) as SecurityCacheItem;

      if (item == null && createIfNull)
      {
            item = new SecurityCacheItem();
            securityCacheManager.Add(token.Value, item, CacheItemPriority.Normal, null, GetCacheExpirations());
      }

      return item;
}

Everything would still be okay had the memory based cache been used. However, when IsolatedStorageBackingStore class is used, the item variable would be written directly to disk, thus becoming another copy that this line of code in the method SavePrincipal() would not work:

 

GetSecurityCacheItem(token, true).Principal = principal;

 

Simply because the resulting SecurityCacheItem would be stored in disk before the Principal property is set. 

Is this a defect or am I missing something here? I would appreciate your comments on this. 

Regards,

Jay

 


 

Mar 2, 2011 at 8:25 AM

I was able to repro your case.  I'll keep you posted for any updates on my investigation.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Mar 2, 2011 at 11:15 AM

This indeed looks like a bug.   I modified the EntLib source code by adding another overload of the GetSecurityCacheItem that accepts an IPrincipal object so that it assigns that to the SecurityCacheItem that gets created prior to adding it to the security cachemanager and it works as expected; I was able to retrieve the IPrincipal object even after the application restarted.  

I created an item for this in the Issue Tracker so you can vote for it. 

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com


Mar 2, 2011 at 11:39 PM

Hi Sarah,

Thank you for your analysis.

Has your changes gone to the source code repository yet? How could I get the fix?

May I know when could we expect this fix would be released formally?

Thanks,

Dikhi

Mar 3, 2011 at 12:19 AM

Hi Sarah, 

Thank you, your prompt reply is much appreciated. 

On you last post you said that you created an overload that takes IPrincipal as an additional parameter - this is what I did when I realized that something is wrong with the approach. I understand that it was just your quick fix to verify the bug, but I just thought I'd share my two cents anyway.

From what I can see there, the method GetSecurityCacheItem() is designed not only to add new entry to the cache but also change existing entry and looks to me that it was made with assumption that if the cache item will synchronize itself to the actual stored object - which would be true if it's in-memory cache. An illustration of what I have in mind, assuming we have two overloads each for IIdentity and IPrincipal: 

MyToken someToken = new MyToken(someGuid);
MyIdentity someIdentity = new MyIdentity(someName);
MyPrincipal somePrincipal = new MyPrincipal();

GetSecurityCacheItem(someToken, true, someIdentity);
GetSecurityCacheItem(someToken, true, somePrincipal);

Granted, above code is probably unlikely since I can getaway with just saving the Principal. However, if by any chance the code above is executed I don't think the IsolatedStorageBackingStore would be able to save the Principal (I could of course be wrong here). 

Just in case someone missed that.

Jay.

Mar 4, 2011 at 12:34 AM
Edited Mar 4, 2011 at 1:13 AM

Jay,

Yes I only meant it as a quick check :), not an official proposed fix.  Anyway, just as a reference, this is what I did:

public override void SaveIdentity(IIdentity identity, IToken token)
{
            GetSecurityCacheItem(token, identity, true); //modified so that the assigning of the identity object o Identity property is being done in GetSecurityCacheItem
}
 
private SecurityCacheItem GetSecurityCacheItem(IToken token, IIdentity identity, bool createIfNull)
{
            SecurityCacheItem item = null;
            item = securityCacheManager.GetData(token.Value) as SecurityCacheItem;

            if (item == null && createIfNull)
            {
                item = new SecurityCacheItem();
                item.Identity = identity; //inserted
                securityCacheManager.Add(token.Value, item, CacheItemPriority.Normal, null, GetCacheExpirations());
            }

            return item;
}
 

dikhi,

The code changes I made is just something I did on my end, and as mentioned, it's just something I did to verify if there's really a bug and check if it fixes that.  The earliest time it could be fixed is when the next version comes out which there's no news yet.  For now, what you can do is to get people to vote for the item in the Issue Tracker.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com