Monday, December 10, 2012

DI, Factories and the Composition Root

Make sure to read a follow-up version of this article.

This tutorial assumes you know what DI/IoC is but you are still unsure how to use it in complex scenarios.

Let me start with a common issue. Somewhere deep in your solution, in an assembly, there is a business service:

public interface IBusinessSerivce 
{
    void DoSomeWork();
}

Then, possibly in yet another assembly you have a class which uses the service:

public class SomeAnotherClass
{
    public void DoThat()
    {
        IBusinessSerivce service = ???
    }
}

How are you supposed to satisfy the dependency here?

There are at least few possible approaches here. Assuming you don’t want a concrete class to be instantiated here, you are left with three possibilities. Let us discuss them one by one.

First possibility – would be to use a service locator. A service locator acts just like a powerful magician – it can show up anywhere in your code and create any service you want (assuming it was registered in the IoC container):

public class SomeAnotherClass
{
    public void DoThat()
    {
        IBusinessSerivce service = 
            ServiceLocator.Current.GetInstance<IBusinessSerivce>();
    }
}

Yep, a kind of magic indeed. No additional dependencies, clean code.

But … is it really? Well, there is one additional dependency! To be able to use the locator, you had to make your project dependant on the locator implementation!

Is this wrong? Possibly. The class library is no longer self-contained. If you distribute it in a binary form, you have to include all the stuff which comes with the locator, one (or more) additional libraries.

Yet another reason a locator is bad is that although the dependency exists (SomeAnotherClass depends on IBusinessService), it is so implicit, so intimate, that any client of SomeAnotherClass would not be aware of the dependency. It’s just, “ok, let me use the class and … boom! I got an exception in runtime because the locator was not able to resolve the service and this was because the implementation had not been registered in the container but how the hell I was supposed to know that the class requires the service implementation to be registered? By studying the implementation?”

This is why the Service Locator is currently considered an anti-pattern.

Another possibility – but let just introduce it for the sake of completeness – would be to actually introduce an explicit dependency to … the container:

public class SomeAnotherClass
{
    private IUnityContainer container { get; set; }
 
    public SomeAnotherClass( IUnityContainer container )
    {
        this.container = container;
    }
 
    public void DoThat()
    {
        IBusinessSerivce service = 
            container.Resolve<IBusinessSerivce>();
    }
}

Well, at least one problem goes away – this time the dependency is explicit and the client of SomeAnotherClass must satisfy it in an explicit way. The other problem remains however, the dependency to the IoC container infrastructure. It just doesn’t look good. Surprisingly, I sometimes see people coding like this.

An ultimate possibility – because SomeAnotherClass depends on the service, let’s make this dependency explicit:

public class SomeAnotherClass
{
    private IBusinessSerivce service { get; set; }
 
    public SomeAnotherClass( IBusinessSerivce service )
    {
        this.service = service;
    }
 
    public void DoThat()
    {
        IBusinessSerivce service = this.service;
    }
}

Great, the dependency is explicit and the other dependency – to the IoC infrastructure is gone. And although this approach can possibly lead to other issues (namely the “constructor over-injection antipattern”) these can possibly be resolved somehow or somehow else.

Problem solved.

Is it, really?

Unfortunately, no. This is where the problem starts! By making the dependency explicit, we just throw the issue away. But it just hits someone else, directly in the face. Because now the client of SomeAnotherClass has exactly the same problem!

public class SomeClass
{
    public void DoThis()
    {
        SomeAnotherClass another = new SomeAnotherClass( ??? );
        another.DoThat();
    }
}

Well, to satisfy the dependency between SomeAnotherClass and IBusinessService I need an instance of the latter. And how do I resolve it?

Well, there are three possibilities, we’ve just discussed them :) And we concluded that the best we could do is to make the dependency explicit:

public class SomeClass
{
    private IBusinessSerivce service { get; set; }
 
    public SomeClass( IBusinessSerivce service )
    {
        this.service = service;
    }
 
    public void DoThis()
    {
        SomeAnotherClass another = new SomeAnotherClass( this.service );
        another.DoThat();
    }
}

This doesn’t look good, unfortunately and this is the core of the problem. By having multiple services in your system and multiple dependencies between various classes, this approach would end up in an object graph where each class depends on all possible services because possibly one of its dependant classes (or the class two, three or more nodes away in the dependency graph) depends on it!

Can you see it? You just can’t rethrow the responsibility to satisfy class dependencies to the client of the class because the client has its clients and they have their clients, too. The sole point of writing this entry is to show how to stop this madness of endless explicit dependencies which would flood your system.

But let us recap facts.

1. SomeAnotherClass really depends on the service because it makes use of it (DoThat method).

2. SomeClass doesn’t really depend on the service, it just depends on SomeAnotherClass. And to resolve the dependency, the SomeClass must somehow create an instance of the service.

3. Most probably we still want the IoC container to register/resolve the concrete implementation of the service but in the same time we don’t want SomeClass to depend on the service locator and/or the container in an explicit way.

And to cope with the issue we are going to introduce a factory. The factory will let its clients to create instances of the service. But we don’t want a concrete factory as it would end up with one, specific way of providing instances. Instead, we want the factory to be parametrized. We want a concrete implementation of the factory to be provided for the system.

For this to work, we will need a conrete class, a factory provider, which will be responsible for registering and providing a concrete implementation of the factory.

public interface IBusinessServiceFactory
{
    IBusinessSerivce CreateService();
}
 
public class BusinessServiceFactoryProvider
{
    public static IBusinessServiceFactory Factory { get; private set; }
 
    /// <summary>
    /// To be called in the Composition Root
    /// </summary>
    public static void SetupFactory( IBusinessServiceFactory factory )
    {
        Factory = factory;
    }
}

Now I can go back to my SomeClass, the one which has to satisfy the dependency to the service but is not itself dependant on the service:

public class SomeClass
{
    public SomeClass()
    {
    }
 
    public void DoThis()
    {
        var factory = BusinessServiceFactoryProvider.Factory;
 
        SomeAnotherClass another = new SomeAnotherClass( factory.CreateService() );
        another.DoThat();
    }
}

(#side note for purists who do not like static properties: the factory provider can be implemented to hide the lifetime of the factory:

public class BusinessServiceFactoryProvider
{
    private static IBusinessServiceFactory _factory { get; private set; }
 
    public IBusinessServiceFactory Factory
    {
        get
        {
            return _factory;
        }
    }
 
    /// <summary>
    /// To be called in the Composition Root
    /// </summary>
    /// <param name="factory"></param>
    public static void SetupFactory( IBusinessServiceFactory factory )
    {
        _factory = factory;
    }
}

so that the client code now becomes

public class SomeClass
 {
     public SomeClass()
     {
     }
 
     public void DoThis()
     {
         var factoryProvider = new BusinessServiceFactoryProvider();
         var factory = factoryProvider.Factory;
 
         SomeAnotherClass another = new SomeAnotherClass( factory.CreateService() );
         another.DoThat();
     }
 }

or even

public class BusinessServiceFactoryProvider
{
    private static IBusinessServiceFactory _factory { get; private set; }
 
    public IBusinessServiceFactory Factory
    {
        get
        {
            return _factory;
        }
    }
 
    /// <summary>
    /// To be called in the Composition Root
    /// </summary>
    /// <param name="factory"></param>
    public static void SetupFactory( 
       Func<IBusinessServiceFactory> factoryCreationMethod )
    {
        _factory = factoryCreationMethod();
    }
}

which makes it possible to implement arbitrary lifetime policy of the factory

#end of side note)

The factory provider really solves the issue once for all. I can provide a concrete implementation of the factory by making the configuration of the factory provider a part of the Composition Root:

class Program
{
    static void Main( string[] args )
    {
        ConfigureContainer();
 
        SomeClass sc = new SomeClass();
        sc.DoThis();
 
        Console.ReadLine();
    }
 
    static void ConfigureContainer()
    {
        IUnityContainer container = new UnityContainer();
 
        // register the service implementation
        container.RegisterType<IBusinessSerivce, BusinessServiceImpl>();
 
        // configure the factory provider
        BusinessServiceFactoryProvider.SetupFactory( 
          () => 
             new ContainerBusinessServiceFactory( container ) );
    }
 
}
 
class ContainerBusinessServiceFactory : IBusinessServiceFactory
{
    #region IBusinessServiceFactory Members
 
    private IUnityContainer container { get; set; }
 
    public ContainerBusinessServiceFactory( IUnityContainer container )
    {
        this.container = container;
    }
 
    public IBusinessSerivce CreateService()
    {
        return container.Resolve<IBusinessSerivce>();
    }
 
    #endregion
}

Note that the ContainerBusinessServiceFactory is just a concrete implementation of the service factory and although it strongly depends on the container infrastructure, it does not really matter as the class is now a part of the Composition Root – it is defined close to the Main method which plays the role of the CR. In the same time the concrete implementation of the service factory class is not really important to its clients as they access the factory by using the provider. The key features of such approach are:

1. All the clients of the service do not depend on the container infrastructure, instead they depend on the factory provider

2. A concrete implementation of the factory can (and possibly should) depend on the container but since it is a part of the composition root, it frees other classes from being dependant on the container infrastructure

3. The intention of the factory provider is now clean and it is safe to make it a required part of the CR. I could even provide a default implementation of the factory which by convention uses the container to resolve service (because most probably this is what I’d really want to do) so that no configuration of the factory provider is necessary at all in the Composition Root. This would introduce a possible issue however – because now a default service provider would depend on the container infrastructure (so that we are back in the situation where the service library has to be distributed together with container libraries).

4. I can freely change the implementation of the factory provider so that the code uses another, more sophisticated conrete factory but this does not influence any client code at all

Happy coding.

Friday, October 19, 2012

Incorrect “Copy Local” value upon checkout from the source control repository

The “Copy Local” setting of your referenced assemblies is stored in the *.csproj file. Take a look at this example fragment:

<Reference Include="Foo.Bar.Qux">
  <HintPath>..\Foo.Bar.Qux.dll</HintPath>
  <Private>True</Private>
</Reference>

This particular fragment of a *.csproj defines the reference to the Foo.Bar.Qux.dll which could be found in a particular location but also has the Copy Local set to True (note that “Copy Local” is referenced here as “Private”).

The issue we have observed is that when you just add references to your assemblies, Visual Studio deduces the value of the “Copy Local” somehow (how?) but doesn’t necessarily persist this “deduction” as a particular value of the “Private”. The “Private” is just missing and the project file says just that:

<Reference Include="Foo.Bar.Qux">
   <HintPath>..\Foo.Bar.Qux.dll</HintPath>
</Reference>

And then comes the issue we have observed.

You see, if you check out your code from the repository to another machine, most of the times the Copy Local will have the correct value – this still unidentified “deduction” will return the same value even though the explicit value is missing from the project file.

And then someday you checkout your code somewhere just to find out that 19 of 20 references has correct values but one of them (it is not “special” in any way!) has not (this happened to us)!

The solution to this unexpected issue is not to rely on the default deduction but always CLICK the value in VS Properties window once or twice to set it to expected value. When you click it in VS, the

<Private>True</Private>

or

<Private>False</Private>

is always added to the project file and then there is no need for any deduction as the explicit value is available.

Thursday, September 6, 2012

SessionAuthenticationModule and dynamic authorization

In my last blog post I’ve described a method to replace the FormsAuthenticationModule with the SessionAuthenticationModule. As it turned out, the SessionAuthenticationModule has some advantages over the forms module. Please refer to the article for more details.

Specifically, the last part of the article is about authorization. What I said is that you can create your roles as claims and the module will serialize roles into the authentication cookie. Then, upon each request the user roles are retrieved from the cookie.

Forms authentication have a clear distinction between static and dynamic role management scenarios - each role provider has the CacheRolesInCookie property (http://msdn.microsoft.com/en-us/library/system.web.security.roles.cacherolesincookie.aspx) which switches between static and dynamic management: when the property is false, the role provider fires at each request, when it is true, roles are cached in a cookie.

Note that from the two scenarios, the latter (storing roles in a cookie) is a direct counterpart of our SessionAuthenticationManager scenario, where roles (claims of type Role) were cached in a cookie.

But what if you want to have your roles assigned dynamically, upon each request? Not only just when you authenticate a user for the first time?

The answer is – create your own claims authentication manager. In theory, the authentication manager fires at each request in the processing pipeline and allows you to inject custom claims to existing identity. I’ve blogged about it some time ago.

The practice is, unfortunately, slightly different. In fact, the authentication manager does not fire at each request! This is because the implementation of the SessionAuthenticationModule contains a strong condition:

// SAM class
public class SessionAuthenticationModule : HttpModuleBase
{   
  protected virtual void OnPostAuthenticateRequest(object sender, EventArgs e)
  {
    if (!(HttpContext.Current.User is IClaimsPrincipal))
    {
      IClaimsPrincipal claimsPrincipal = ClaimsPrincipal.CreateFromHttpContext(HttpContext.Current);
      ClaimsAuthenticationManager claimsAuthenticationManager = base.ServiceConfiguration.ClaimsAuthenticationManager;
      if (claimsAuthenticationManager != null && claimsPrincipal != null && claimsPrincipal.Identity != null)
      {
        claimsPrincipal = claimsAuthenticationManager.Authenticate(HttpContext.Current.Request.Url.AbsoluteUri, claimsPrincipal);
      }
      HttpContext.Current.User = claimsPrincipal;
      Thread.CurrentPrincipal = claimsPrincipal;
    }
  }
}

You see the condition in the provided implementation? If the current user is not an claims principal then fire the authentication manager.

When does it happen? There are two possible scenarios:

  • the user is not yet authenticated
  • the user is authenticated by another authentication module (like the forms authentication module)

The third scenario: the user is authenticated by the SessionAuthenticationModule is not handled by this condition! The claims authentication manager will not run.

To fix this and have the manager executed even when a user is authenticated and the identity comes from the SAM, I just have to provide a counterpart implementation:

public class Global : System.Web.HttpApplication
{
    void Application_PostAuthenticateRequest( object sender, EventArgs e )
    {
        // handle the missing scenario
        if ( HttpContext.Current.User is IClaimsPrincipal )
        {
            IClaimsPrincipal claimsPrincipal = HttpContext.Current.User as IClaimsPrincipal;
            ClaimsAuthenticationManager claimsAuthenticationManager = 
                FederatedAuthentication.ServiceConfiguration.ClaimsAuthenticationManager;
            if ( claimsAuthenticationManager != null && 
                 claimsPrincipal != null && claimsPrincipal.Identity != null )
            {
                // and execute the manager
                claimsAuthenticationManager.Authenticate( HttpContext.Current.Request.Url.AbsoluteUri, claimsPrincipal );
            }
            //HttpContext.Current.User = claimsPrincipal;
            //Thread.CurrentPrincipal = claimsPrincipal;
        }
    }

As you can see, this was added to the global application class and is merely a copy-paste from the SAM’s implementation but what I change is the condition – the condition is complementary to the one from SAM. The authentication manager is always executed then – first two described scenarios are handled by SAM, the last one – by this snippet above.

Ultimately, the claims authentication manager can be used now to manage roles dynamically as role claims can be dynamically injected in each separate request in the processing pipeline.

Wednesday, September 5, 2012

Forms Authentication revisited

Forms authentication is an authentication module, known for years and quite reliable. The core idea is that the authentication pipeline takes the so called forms authentication cookie, decrypts the cookie and sets the HttpContext.Current.User for a request. Forms authentication subsystem contains an API which can issue cookies, in particular you can attach a small portion of custom data to the cookie so that the data is available as long as the user is logged in.

Issues

There are two common issues around the Forms authentication module: the custom data cannot be too long and because it is a string – there is no natural way to make it “compound” (contain a structure of few fields).

The second issue can possibly be solved by creating your own structure (XML for example), serializing and deserializing the data. Nothing out of the box.

However, I haven’t found any solution to the the first issue. Let’s face it:

string ReallyLongUserData
{
    get
    {
        Random r = new Random();
 
        StringBuilder sb = new StringBuilder();
 
        while ( sb.Length < 8192 )
            sb.Append( r.Next().ToString() );
 
        return sb.ToString();
    }
}
 
...
 
// create a forms cookie with really long userdata (>8192)
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
    1, txtUserName.Text, DateTime.Now, 
    DateTime.Now.AddMinutes( 20 ), false, ReallyLongUserData );
 
HttpCookie cookie = new HttpCookie( FormsAuthentication.FormsCookieName );
cookie.Value = FormsAuthentication.Encrypt( ticket );
this.Response.AppendCookie( cookie );
 
Response.Redirect( this.Context.Request.QueryString["ReturnUrl"] );

Guess what happens if you run this.

The answer is: the cookie is signed and encrypted and appended to the response. But apparently, the cookie size clearly exceedes the maximum size of the cookie browsers can handle. Most browsers ignore the cookie then! The cookie is missing from subsequent requests.

SessionAuthenticationModule for the rescue!

If there’s a way to replace the FormsModule with a custom module capable of handling multiple cookies, then the cookie size issue would just be gone. Let the module just split the long value to multiple cookies, TheCookie1, TheCookie2, … and then, at the server, join the cookie data and recreate the identity. And what if the module supports multiple userdata entries, a dictionary which maps keys to values possibly?

Sounds great?

Well, there IS such module. It is called SessionAuthenticationModule.

It is part of the Windows Identity Foundation and normally it is used in federation scenarios where identity cookie is issued according to SAML tokens from identity providers (here it doesn’t really matter what a SAML token is). If you work with WIF, you know the module.

However, the SessionAuthenticationModule can be used in a normal application, just to replace the incapable Forms module and provide additional features.

First, the configuration:

<configuration>
 
    <configSections>
        <section name="microsoft.identityModel" type="Microsoft.IdentityModel.Configuration.MicrosoftIdentityModelSection, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </configSections>
 
    <system.web>
 
        <authentication mode="Forms">
            <forms loginUrl="LoginPage.aspx" />
        </authentication>
        
        <authorization>
            <deny users="?"/>
            <allow users="*"/>
        </authorization>
 
        <httpModules>
            <add name="SessionAuthenticationModule" 
                 type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, 
                       Microsoft.IdentityModel, Version=3.5.0.0, 
                       Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        </httpModules>
 
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
 
    <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
        <modules>
            <add name="SessionAuthenticationModule" 
                 type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, 
                       Microsoft.IdentityModel, Version=3.5.0.0, 
                       Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="managedHandler" />
        </modules>
    </system.webServer>
 
    <microsoft.identityModel>
        <service>
            <federatedAuthentication>
                <cookieHandler name="ADWebFrontEndCookie" requireSsl="false" />
            </federatedAuthentication>
        </service>
    </microsoft.identityModel>
 
</configuration>

Note that I declare that I am using Forms module. This is to utilize the Forms ability to authorize Url access and redirect the browser to the login page in case of insufficient priviledges. The SAM module’s cookie name is also declared in the module’s section.

And there comes the code:

string ReallyLongUserData
 {
     get
     {
         Random r = new Random();
 
         StringBuilder sb = new StringBuilder();
 
         while ( sb.Length < 8192 )
         //while ( sb.Length < 512 )
             sb.Append( r.Next().ToString() );
 
         return sb.ToString();
     }
 }
 
...
SessionAuthenticationModule sam = 
   (SessionAuthenticationModule)
   this.Context.ApplicationInstance.Modules["SessionAuthenticationModule"];
 
IClaimsPrincipal principal = 
   new ClaimsPrincipal( new GenericPrincipal( new GenericIdentity( txtUserName.Text ), null ) );
 
// create any userdata you want. by creating custom types of claims you can have
// an arbitrary number of your own types of custom data
principal.Identities[0].Claims.Add( new Claim( ClaimTypes.Email, "foo@bar.com" ) );
principal.Identities[0].Claims.Add( new Claim( ClaimTypes.UserData, ReallyLongUserData ) );
 
var token = 
    sam.CreateSessionSecurityToken( 
        principal, null, DateTime.Now, DateTime.Now.AddMinutes( 20 ), false );
sam.WriteSessionTokenToCookie( token );
 
Response.Redirect( this.Context.Request.QueryString["ReturnUrl"] );
     

This code replaces the previous code – instead of issuing a Forms cookie, now I am issuing a SAM cookie.

And …. that’s it. The cookie is created, it is automatically split into smaller cookies so that the browser’s limit doesn’t break anything. Also, now I can easily create any type of custom data I want by mapping claim types to values. Note that multiple claims of the same type can be assigned to the identity.

Authorization with the SAM module

Another surprizing benefit of using the SAM module is that it simplifies role management and authorization. Upon each request, the module recreates the identity which is of type ClaimsPrincipal. This class has the IsInRole method already implemented. And the way you feed it with roles is straightforward:

IClaimsPrincipal principal = 
   new ClaimsPrincipal( 
      new GenericPrincipal( new GenericIdentity( txtUserName.Text ), null ) );
principal.Identities[0].Claims.Add( new Claim( ClaimTypes.Email, "foo@bar.com" ) );
principal.Identities[0].Claims.Add( new Claim( ClaimTypes.UserData, ReallyLongUserData ) );
 
// roles, stored in the cookie as claims!
principal.Identities[0].Claims.Add( new Claim( ClaimTypes.Role, "ADMIN" ) );

It turns out then that you don’t really have to change much in your application - the authorization should work, including the static authorization with authorization sections of web.config files. What you only need to provide is to add role claims when you create the principal object.

Happy coding.

Indexing attributes in the Active Directory

The default Microsoft Active Directory schema is full of attributes. If you by chance pick some unused attributes and reuse them for your own purposes, there’s a caveat – some attributes are indexed and some other are not. And as you can expect – this makes a huge difference if your business processing relies on searching the AD database.

Fortunately, AD can be reconfigured to create an index over any attribute. These articles describe all required steps:

http://technet.microsoft.com/en-us/library/cc755885(WS.10).aspx

http://technet.microsoft.com/en-us/library/aa995762(EXCHG.65).aspx

In short:

  1. You have to be in “Schema Admins” AD group
  2. You have to install the Active Directory Schema MMC snapin (just regsvr32.exe schmmgmt.dll and the snapin will be available)
  3. Run the snapin “as the administrator” from the shell
  4. Locate your attribute, double click it and check both “Index this attribute” and (optionally) “Replicate this attribute to the Global Catalog”