Windows Identity Foundation not removing Session Security Token from Cache

Recently were I work we had a PEN test on one of our applications and that highlighted that the federated authentication token for a relying party wasn’t being cleaned up correctly when logging out. After sitting down and working out what was cause for this problem I thought I would share my findings and the solution.

The problem

At work we use a custom session security token cache to store the token so we don’t have to pass around so much data to and from the client. When logging out from a replying party using a federated sign out e.g. “wsignoutcleanup1.0” the WIF code base should use the federation authentication module (FAM) and the “SignOut” method to get the session authentication module (SAM) and tidy up/delete the current session token. See the code example 1 below.

Example 1

public virtual void SignOut(bool isIPRequest)
{
  try
  {
    this.OnSigningOut(new SigningOutEventArgs(isIPRequest));
    SessionAuthenticationModule.Current.DeleteSessionTokenCookie();
    this.OnSignedOut(EventArgs.Empty);
  }
} 

The session authentication module and its method “DeleteSessiontokenCookie” then checks that the property “ContextSessionSecurityToken” isn’t null before calling the actual code to remove the session security token from the persistent cache and the in memory one. See example 2 below.

Example 2

public void DeleteSessionTokenCookie()
{
  this.CookieHandler.Delete();
  if (this.ContextSessionSecurityToken == null)
    return;
  this.RemoveSessionTokenFromCache(this.ContextSessionSecurityToken);
}

Now debugging the code and decompiling it I was able to work out that the session authentication module sets the “ContextSessionSecurityToken” when the “OnAuthenticateRequest” event is handled in the SAM. However, when signing out from the RP using “wsignoutcleanup1.0” this event is not fired or handled by the SAM if the FAM is defined above it in the web.config modules section (see below). No you read that correctly the order of the FAM and SAM in the web config appear to determine whether your token is cleared from the cache or not!

Does not remove the item from the cache

<removename="FormsAuthentication" />

<add name="WSFederationAuthenticationModule"
  type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  preCondition="managedHandler" />

<add name="SessionAuthenticationModule" 
  type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  preCondition="managedHandler" />

The fix

Now, I’m not certain but I do not believe an application should be dependent on the order of HTTP modules to function correctly. Am I missing something? A quick fix for us is indeed to switch the order of the modules in the web.config to get the “ContextSessionSecurityToken” to be set (See example modules below).

<remove name="FormsAuthentication" />

<add name="SessionAuthenticationModule" 
  type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
  preCondition="managedHandler" />

<add name="WSFederationAuthenticationModule" 
  type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
  preCondition="managedHandler" />

Additionally I can also add some code to the FAM to do manually set the property on the SAM (see below). Both approaches feel wrong to me in that they fix an issue in the underline WIF implementation. Well potential issue…

FAM change

public override void SignOut(bool isIPRequest)
{
  var sessionModule = FederatedAuthentication.SessionAuthenticationModule;
  SessionSecurityToken token;
  var hasManagedToRead = sessionModule.TryReadSessionTokenFromCookie(out token);
  if (hasManagedToRead)
  {
    var lafSam = sessionModule asLafSessionAuthenticationModule;
    lafSam.ContextSessionSecurityToken = token;
  }
  sessionModule.DeleteSessionTokenCookie();
  base.SignOut(isIPRequest);
}

SAM change (redefined property in the LAF custom SAM so I could set the property!

public SessionSecurityToken ContextSessionSecurityToken
{
  get
  {
    return (SessionSecurityToken)HttpContext.Current.Items[(object)typeof(SessionSecurityToken).AssemblyQualifiedName];
  }
  set
  {
    HttpContext.Current.Items[(object)typeof(SessionSecurityToken).AssemblyQualifiedName] = (object)value;
  }
}

Until next time.

May 13 2014

Shouldn’t validating a checkbox be easier than this?

 

Well it's been a while since I have done a post but with changing jobs recently and life in general getting in the way I just couldn’t seem to find the time. However, now I have a spare five minutes I thought I would fire off a post :)

So what's the post about? Validating a checkbox web control. Now I know your reading this thinking that's easy all you need is a custom validator and a event handler in your code behind and job done? Well in most cases yes I would agree with you. However, my latest project (a legacy application) uses code generation to create the vast majority of the ASP.NET pages and user controls. Therefore it’s difficult for me to include anything other than the standard set of ASP.NET validators or something which inherits off the “BaseValidator” and get it working correctly in the XSLT templates generating the code. Because of this I decided to create my own validator for the checkbox web control.

So how do we get started? Well first off you need to inherit off the “BaseValidator” and then override the required "EvaluateIsValid" method. Once done you can then write some simple logic to ensure your checkbox has been checked. As shown below.

   1:  public class CheckBoxValidator : BaseValidator
   2:  {
   3:      protected override bool EvaluateIsValid()
   4:      {
   5:          var controlValue = this.GetControlValidationValue(this.ControlToValidate);
   6:          bool checkBoxValue;
   7:          var hasBeenParsed = bool.TryParse(controlValue, out checkBoxValue);
   8:   
   9:          var result = hasBeenParsed && checkBoxValue;
  10:          return result;
  11:      }
  12:  }

 

So is that it all done? Well no because the out of the box checkbox control is missing an important thing. The "ValidationProperty" attribute. This attribute is used within the base validator to work out which property on the control being validated should to used when getting the control validation value. In order to solve this problem you will need to create your own version of the checkbox control by inheriting from it and adding the required attribute as shown below.

   1:  [ValidationProperty("Checked")]
   2:  public class ValidationCheckBox : CheckBox
   3:  {
   4:  }

 

Ok so now we have our own custom checkbox and checkbox validator we can finally validate those lovely checkboxes. However, if you recall from a bit earlier I said this is a legacy application and although it is to a large degree generated for me I'm not sure I really want to find all the places where a standard checkbox web control should be switched out for my super custom one. So what's the answer? Tag mapping.

Now tag mapping if you haven't heard of it before enables you to define within the web.config that tag "A" should instead be mapped to tag "B". You can see below how I used it to always return my custom checkbox whether a standard asp.net checkbox should be used.

  1: <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
  2:   <tagMapping>
  3:     <add tagType="System.Web.UI.WebControls.CheckBox" mappedTagType="Demo.Web.Code.Controls.ValidationCheckBox" />
  4:   </tagMapping>
  5: </pages>
Now that’s done I don’t have to change a single line of code to get my new checkbox control in place and get my validations working. One finial point though or really a question is why haven’t Microsoft just created this type of validator and given it to me straight out of the box? Yes I know I could change the checkbox to some radio buttons to achieve a similar thing, but sometimes I don’t get the finial say in the design of a page and this type of validator would come in handy I think for a lot of people.
April 6 2011

Bob the builder

I recently started a new project which is very focused on having good test coverage which is great goal to have.  However, looking through their tests I started to notice a lot of setup code which was very similar and looked a lot like the following:

   1: [TestMethod]
   2: public void WhenTheAddressRepositoryIsAskedToAPersistAddressesItShouldCorrectlyPersistThoseAddresses()
   3: {
   4:     // Arrange
   5:     var addressesToPersist = new List<Address>();
   6:  
   7:     var address = new Address
   8:                           {
   9:                               AddressLine1 = Guid.NewGuid().ToString(),
  10:                               AddressLine2 = Guid.NewGuid().ToString(),
  11:                               AddressLine3 = Guid.NewGuid().ToString(),
  12:                               AddressLine4 = Guid.NewGuid().ToString(),
  13:                               City = Guid.NewGuid().ToString(),
  14:                               County = Guid.NewGuid().ToString(),
  15:                               CountryCode = Guid.NewGuid().ToString(),
  16:                               Postcode = Guid.NewGuid().ToString()
  17:                           };
  18:     addressesToPersist.Add(address);
  19:  
  20:     var address1 = new Address
  21:                            {
  22:                                AddressLine1 = Guid.NewGuid().ToString(),
  23:                                AddressLine2 = Guid.NewGuid().ToString(),
  24:                                AddressLine3 = Guid.NewGuid().ToString(),
  25:                                AddressLine4 = Guid.NewGuid().ToString(),
  26:                                City = Guid.NewGuid().ToString(),
  27:                                County = Guid.NewGuid().ToString(),
  28:                                CountryCode = Guid.NewGuid().ToString(),
  29:                                Postcode = Guid.NewGuid().ToString()
  30:                            };
  31:     addressesToPersist.Add(address1);
  32:  
  33:     var addressRepository = new AddressRepository();
  34:     
  35:     // Act
  36:     addressRepository.Persist(addressesToPersist);
  37:     var actualPersistedAddresses = addressRepository.GetAll();
  38:     
  39:     // Assert
  40:     Assert.IsNotNull(actualPersistedAddresses);
  41:     Assert.AreEqual(2, actualPersistedAddresses.Count);
  42: }

Now the above code isn’t all that bad in a single test but what happens when you start to write more tests?  Well you could copy and paste the code for creating addresses from test to test which will certainly work but you end up with a lot of very similar code which you have to maintain going forward and update whenever a new address property is added or removed.  All this sounds like a lot of work plus it goes against the DRY principle.  DRY for those of you who don’t know means “Don’t Repeat Yourself”.  The principle encourages that duplication within an application is removed as every line of  code written has to be maintained and each line of code can cause bugs. More importantly the principle is about having a single source of knowledge within a system and then using that source to generate instances of that knowledge. In this case the instances of knowledge would be the address objects which are being created within each unit test.  The question then is how do we create something which we can use as the source of that knowledge?

Enter the builder

That single source of knowledge within the project I’m working on is provided by using the object builder pattern. Using this pattern we can have a single and consistent approach to creating the entities within tests and the ability to easily extend those entities within our domain and test data. We can also chain the builders together to create complex test data very quickly.

So how do you create a builder? Well below is my implementation of an address builder to get you going.

   1: public class AddressBuilder : BuilderBase<AddressBuilder, Address>
   2: {
   3:     private int id;
   4:     private string addressLine1 = GetUniqueValueFor();
   5:     private string addressLine2 = GetUniqueValueFor();
   6:     private string addressLine3 = GetUniqueValueFor();
   7:     private string addressLine4 = GetUniqueValueFor();
   8:     private string city = GetUniqueValueFor();
   9:     private string countryCode = "GB";
  10:     private string postCode = "SE1 9EU";
  11:     private string county = "London";
  12:  
  13:     public AddressBuilder WithId(int id)
  14:     {
  15:         this.id = id;
  16:         return this;
  17:     }
  18:    
  19:     public AddressBuilder WithAddressLine1(string addressLine1)
  20:     {
  21:         this.addressLine1 = addressLine1;
  22:         return this;
  23:     }
  24:  
  25:     public AddressBuilder WithAddressLine2(string addressLine2)
  26:     {
  27:         this.addressLine2 = addressLine2;
  28:         return this;
  29:     }
  30:  
  31:     public AddressBuilder WithAddressLine3(string addressLine3)
  32:     {
  33:         this.addressLine3 = addressLine3;
  34:         return this;
  35:     }
  36:  
  37:     public AddressBuilder WithAddressLine4(string addressLine4)
  38:     {
  39:         this.addressLine4 = addressLine4;
  40:         return this;
  41:     }
  42:  
  43:     public AddressBuilder WithCity(string city)
  44:     {
  45:         this.city = city;
  46:         return this;
  47:     }
  48:  
  49:     public AddressBuilder WithCountry(string countryCode)
  50:     {
  51:         this.countryCode = countryCode;
  52:         return this;
  53:     }
  54:  
  55:     public AddressBuilder WithPostCode(string postCode)
  56:     {
  57:         this.postCode = postCode;
  58:         return this;
  59:     }
  60:  
  61:     public AddressBuilder WithCounty(string county)
  62:     {
  63:         this.county = county;
  64:         return this;
  65:     }
  66:  
  67:     public override Address Build()
  68:     {
  69:         var address = new Address
  70:                           {
  71:                               Id = this.id,
  72:                               AddressLine1 = this.addressLine1,
  73:                               AddressLine2 = this.addressLine2,
  74:                               AddressLine3 = this.addressLine3,
  75:                               AddressLine4 = this.addressLine4,
  76:                               City = this.city,
  77:                               CountryCode = this.countryCode,
  78:                               County = this.county,
  79:                               Postcode = this.postCode
  80:                           };
  81:  
  82:         return address;
  83:     }
  84: }

As you can see the code behind the builder is really very simple with default values assigned to the properties which can then be explicitly set using the “With” methods on the builder. When I’m using builders I also like to add a base for them which provides default behaviour.

   1: public abstract class BuilderBase<TBuilder, TBuild> where TBuilder : BuilderBase<TBuilder, TBuild>
   2: {
   3:     /// <summary>
   4:     /// Builds this instance.
   5:     /// </summary>
   6:     /// <returns></returns>
   7:     public abstract TBuild Build();
   8:  
   9:     /// <summary>
  10:     /// Builds the many.
  11:     /// </summary>
  12:     /// <param name="number">The number.</param>
  13:     /// <returns></returns>
  14:     public List<TBuild> BuildMany(int number)
  15:     {
  16:         var result = new List<TBuild>();
  17:  
  18:         for (int i = 0; i < number; i++)
  19:         {
  20:             var builtItem = this.Build();
  21:             result.Add(builtItem);
  22:         }
  23:  
  24:         return result;
  25:     }
  26:  
  27:     /// <summary>
  28:     /// Gets the unique value for.
  29:     /// </summary>
  30:     /// <returns></returns>
  31:     protected static string GetUniqueValueFor()
  32:     {
  33:         return Guid.NewGuid().ToString();
  34:     }
  35: }

So now we have the address builder this put it all together to create our new and improved unit test.

   1: [TestMethod]
   2: public void WhenTheAddressRepositoryIsAskedToAPersistAddressesItShouldCorrectlyPersistThoseAddresses()
   3: {
   4:     // Arrange
   5:     var addressesToPersist = new AddressBuilder().BuildMany(2);
   6:     var addressRepository = new AddressRepository();
   7:     
   8:     // Act
   9:     addressRepository.Persist(addressesToPersist);
  10:     var actualPersistedAddresses = addressRepository.GetAll();
  11:     
  12:     // Assert
  13:     Assert.IsNotNull(actualPersistedAddresses);
  14:     Assert.AreEqual(2, actualPersistedAddresses.Count);
  15: }

As you can see the duplicate code for creating each address is now gone and we have a nice simple method for creating as many address as we want using the “BuildMany” method provided by the base builder. Well that’s it for now. The complete source code for this example can be found at http://cid-468e9f9e14e99f80.office.live.com/self.aspx/.Public/Blog.Builders.zip

Trouble using the AdvancedFilterSet with the “whenCreated” active directory property

Over the last couple of days on my current project I have been working with the new account management API found in .NET 3.5 for communicating with active directory. This API is a massive improvement over the features provided by the older directory services and really does make creating, deleting, updating and finding users a lot simpler (for more information checkout http://msdn.microsoft.com/en-us/library/bb299745%28v=VS.100%29.aspx).

As part of the work I needed to provide the ability to find users based on the date they were created so following the approach on MSDN (see http://msdn.microsoft.com/en-us/library/bb384372.aspx) I extended the “AdvancedFilters” class and added my own method for setting a filter for a query using the active directory property “whenCreated”. I should say this property stores the date and time a user is created with AD. Now the code shown below is what I first came up with and it looks like it will do the job right?

  1: public class SearchFilter : AdvancedFilters
  2: {
  3:     /// <summary>
  4:     /// Initializes a new instance of the <see cref="SearchFilter"/> class.
  5:     /// </summary>
  6:     /// <param name="p"></param>
  7:     public SearchFilter(Principal p) : base(p)
  8:     {
  9:     }
 10: 
 11:     public void Created(DateTime? created, MatchType matchType)
 12:     {
 13:        if (!created.HasValue) return;
 14:          AdvancedFilterSet("whenCreated", created.Value, typeof(DateTime), matchType);
 15:     }
 16: }
 17: 

Well sadly no. As it turns out the “whenCreated” property in AD is stored as a string in the generalised time format (see http://msdn.microsoft.com/en-us/library/ms680924%28VS.85%29.aspx). Because of this telling the advanced filter set that it’s a date just doesn’t work and you will find as I did no results are returned. So how do you get this to work then? Well all we need to do is update our “Created” method a bit so the advanced filter set thinks it is dealing with a string and then just pass in the date in the correct generalised date format which is “yyyyMMddHHmmss.0Z”.

[Updated code which now correctly sets the type and formats it]
  1: public void Created(DateTime? created, MatchType matchType)
  2: {
  3:    const string WhenCreatedDateFormat = "yyyyMMddHHmmss.0Z";
  4: 
  5:    if (!created.HasValue) return;
  6:    AdvancedFilterSet(ClientUser.WhenCreatedPropertyName,
  7:    created.Value.ToUniversalTime().ToString(WhenCreatedDateFormat), typeof (string), matchType);
  8: }

Once you do this your query filter will spring into life and happily return you results. Well that’s it for now.

April 25 2010
Older Posts