One of the things that seem very simple on a Powerpoint presentation, but are not that simple in practice, is having a web user’s identity forwarded from a calling web application to another web application when using Kerberos.

The case is as follows: I have an intranet application A which uses Integrated Windows Authentication to authenticate the user. During processing of a request from a web users, application A then makes an HTTP request to intranet application B. Application B requires the web user to be authenticated to process the request. The often most attractive solution for solving this is what Microsoft refers to as identity delegation. Simple in a Powerpoint presentation, but alas, not so simple in practice.

First of all, there are a number of preconditions in the computing environment configuration that need to be fulfilled. I found a very good summary of gotchas in this respect here. In my case, the points 2 and 6 was  missing (I knew about the other once beforehand). So, when all configuration stuff set up, then the only thing left is the code and configuration in the application A.

Basically, you need to make the application impersonate the web user (meaning that it will run with the credentials of the web user). There are two ways to do this. If you wish the entire request to run as the web user, you can insert an <identity impersonate=”true” /> element under <system.web> in the application’s web.config. Or, if you wish only the request to application B to run as the web user, you can do this programmatically:

using System.Security.Principal;
...
WindowsIdentity identity = (WindowsIdentity)HttpContext.Current.User.Identity();
using (identity.Impersonate())
{
    // ... code to call application B goes here ...
}

Then, the next task is to call application B itself. You can do this by creating a web request:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.somethingcompletelydifferent.com");
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
request.UseDefaultCredentials = true;
...
HttpWebResponse response = request.GetResponse();
...

The important things to notice here is that we set the ImpersonationLevel property to “Delegation” and that we set the UseDefaultCredentials property to “true”. So, it together, we get:

using System.Security.Principal;
...
WindowsIdentity identity = (WindowsIdentity)HttpContext.Current.User.Identity();
using (identity.Impersonate())
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.somethingcompletelydifferent.com");
    request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
    request.UseDefaultCredentials = true;
    ...
    HttpWebResponse response = request.GetResponse();
    ...
}

You can then test that it works in application B by checking the name in HttpContext.Current.User.Identity.Name.

My experience is that Spring.NET configuration files tend to grow very large. As far as I can figure, there are two principal problems that arise from this:

  1. The configuration files get difficult to read and maintain
  2. It gets easier to introduce errors in the configuration because of its size

In general, I am in favour of keeping configuration files as small as possible. I often work with web applications that can (quite) easily be redeployed to the production environment, hence I always ask the question “will this value ever change between environments or deployments” when considering introducing a new configuration part.

Now, the Spring XML configuration usually serves two main purposes; to wire together the application, and to provide values that should be possible to change between deployments of the application or for different environments. The first purpose, I would argue does not necessarily need to be in the XML configuration. Rather, if this is done in code, we get the benefit that the compiler will tell us right away if there are typos or missing references. If this wiring is in the XML configuration file, such errors will not surface until the application starts.

So, the question that I had, was how Spring context wiring could be combined in code and in XML. I found one way of doing it, but it is only applicable to singleton objects.

Say, for instance that we have an object “something” that we wish to have configured in XML:

  <object id="something" type="SpringTest.Something, SpringTest" singleton="false"/>

Then, we have a class that we want to initialize in code:

class Foo
{
    public Foo() { }
    private Something _s;
    Something S
    {
        set { _s = value; }
        get { return _s; }
    }
}

Now, we see that Foo has a dependency on Something; it needs an instance of Something to be injected. We can use the Spring context to do this after we have created the instance of Foo:

IApplicationContext context = ContextRegistry.GetContext();
Foo f = new Foo();
context.ConfigureObject(f, "fooPrototype");

But Spring does not yet know that the Foo instance needs to be injected Something. Hence, we need to tell Spring that by creating what I would call a “prototype” or “template” object configuration:

<object id="fooPrototype" type="ContextTestProject.Foo, ContextTestProject">
   <property name="S" ref="something"></property>
</object>

The final step is then to register our newly created object in the Spring context:

XmlApplicationContext xmlContext = context as XmlApplicationContext;
xmlContext.ObjectFactory.RegisterSingleton("foo", f);

After this, the Foo instance is available for the application in the Spring context.

One question have troubled me for some time when automating Internet Explorer (actually, I am doing web testing with Watin): how to test for HTTP status codes. Finally, I figured out how to do this. The lies in an event that the InternetExplorer object raises when navigation is unsuccessful.

I ended up with writing a C# helper class:

using System.Net;
using WatiN.Core;
using SHDocVw;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Globalization;
namespace Test
{
    public class NavigationObserver
    {
        private HttpStatusCode _statusCode;
        public NavigationObserver(IE ie)
        {
            InternetExplorer internetExplorer = (InternetExplorer)ie.InternetExplorer;
            internetExplorer.NavigateError += new DWebBrowserEvents2_NavigateErrorEventHandler(IeNavigateError);
        }
        public void ShouldHave(HttpStatusCode expectedStatusCode)
        {
            if (!_statusCode.Equals(expectedStatusCode))
            {
                Assert.Fail(string.Format(CultureInfo.InvariantCulture, "Wrong status code. Expected {0}, but was {1}",
                    expectedStatusCode, _statusCode));
            }
        }
        private void IeNavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
        {
            _statusCode = (HttpStatusCode)StatusCode;
        }
    }
}

Note that I use Visual Studio test runner to run my web tests. Then, I can use this in my test:

using (IE ie = new IE())
{
    NavigationObserver observer = new NavigationObserver(ie);
    ie.GoTo("http://some.where.com");
    observer.ShouldHave(HttpStatusCode.NotFound);
}

When doing web testing using Watin, it is not trivial to be able to do a POST request to the server. However, with the help this article on microsoft.com, I was able to figure out how. I ended up with writing this class:

public class Navigator
{
    private IE _ie;

    public Navigator(IE ie) { _ie = ie; }

    public void Post(Uri baseUri, params KeyValuePair<string, object>[] postData)
    {
        object flags = null;
        object targetFrame = null;
        object headers = “Content-Type: application/x-www-form-urlencoded” + Convert.ToChar(10) + Convert.ToChar(13);
        object postDataBytes = MakeByteStreamOf(postData);
        object resourceLocator = baseUri.ToString();
        IWebBrowser2 browser = (IWebBrowser2)_ie.InternetExplorer;
        browser.Navigate2(ref resourceLocator, ref flags, ref targetFrame, ref postDataBytes, ref headers);
        _ie.WaitForComplete();
    }

    private static byte[] MakeByteStreamOf(KeyValuePair<string, object>[] postData)
    {
        StringBuilder sb = new StringBuilder();
        if (postData.Length > 0)
        {
            foreach (KeyValuePair<string, object> postDataEntry in postData)
            {
                sb.Append(postDataEntry.Key).Append(’=').Append(postDataEntry.Value).Append(’&’);
            }
            sb.Remove(sb.Length - 1, 1);
        }
        return ASCIIEncoding.ASCII.GetBytes(sb.ToString());
    }
}

For example, I can use it like so:

using (IE ie = new IE())
{
    Navigator navigator = new Navigator(ie);
    navigator.Post(new Uri("http://www.foo.com/"), new KeyValuePair<string, object>("p", 1));
    Assert.AreEqual("OK", ie.Text);
}

Encapsulation is one of the most important features of object orientation, but often easy to break in practice. One common mistake to make in this respect happens when creating a class that holds some sort of collection or array.

For example, let’s assume that we want to make an immutable object (meaning that its state should never change troughout its lifecycle):


public class Request
{
    private readonly string[] _acceptedTypes;
    public Request(params string [] acceptedTypes) {…}
    public string[] AcceptedTypes { get {…} }
    public bool Accepts(string type) {…}
}

We have a class that take a list of strings as parameter to the constructor. The intent is that the list of strings should never change. Typical use of the class would be something like this:


Request request = new Request("application/json", "application/x-json");
if (request.Accepts(somestring))
{
     ...
}

Here’s a naîve implementation of the class:


public class Request
{
    private readonly string[] _acceptedTypes;

    public Request(params string[] acceptedTypes)
    {
        _acceptedTypes = acceptedTypes;
    }

    public string[] AcceptedTypes { get { return _acceptedTypes; } }

    public bool Accepts(string type)
    {
        foreach (string acceptableType in _acceptedTypes)
        {
            if (acceptableType.Equals(type))
            {
                return true;
            }
        }
        return false;
    }
}

Our intent of creating an immutable object is here manifested in the ‘readonly’ keyword used when defining the member variable _acceptedTypes, and the fact that there is only a set accessor for the AcceptedTypes property. But alas, there are several issues that break our intent.

First, let’s have a look at the AcceptedTypes accessor. It allows us to write code such as this:


request = new Request("application/json", "application/x-json" );

bool accepts1 = request2.Accepts("application/javascript");
request.AcceptedTypes[1] = “application/javascript”;
bool accepts2 = request.Accepts(”application/javascript”);

After running this code, we find that accepts1 != accepts2. We have been able to manipulate the state of the object (in other words, it is mutable). The problem is that the AcceptedTypes exposes a reference to the array of types. Alternatively, it could only expose an IEnumerable that can be used to iterate over the types:


public IEnumerable AcceptedTypes
{
get
{
    foreach (string acceptableType in _acceptedTypes)
{
yield return acceptableType;
}
    }
}

Then, it will not be possible to manipulate the state of the object by calling request.AcceptedTypes[i].
Still, there is one problem with the current implementation. We still can write code such as this:


string[] types = new string[] { “application/json”, “application/x-json” };
Request request = new Request(types);
bool accepts1 = request.Accepts(”application/javascript”);
types[1] = “application/javascript”;
bool accepts2 = request.Accepts(”application/javascript”);

After running this code, accepts1 != accepts2. The problem is that we pass a referene to the constructor, and the object instance stores it in its local variable. We are free to change the object that our reference points to, indirectly changing the state of the object. In order to fix this, we change the constructor code for Request:


public Request(params string[] acceptedTypes)
{
_acceptedTypes = new string[acceptedTypes.Length];
Array.Copy(acceptedTypes, _acceptedTypes, acceptedTypes.Length);
}

When developing an ASP.NET solution for a customer, I run the application locally on my laptop (IIS 5.1, Win XP). For a realistic test scenario I had set up a separate host name for my local computer in my hosts file. I then enabled my application for Integrated Windows Authentication, and was a bit puzzled by why it did not work.

Internet Explorer did not automatically authenticate me when wisiting the web application. The problem turned out to be that there was no Service Principal Name registered in Active Directory that associated the hostname with my computer. Hence, the client could not request a Kerberos service ticket for my web application.

The solution was to run the setspn.exe tool (available in the Windows Server 2003 Support Tools package) to create the desired SPN entry in Active Directory. For example:

setspn -A HOST/my.fake.hostname.com MYCOMPUTER

(where MYCOMPUTER is the network computer name for my workstation). You have to be a domain administrator to run this command.

The effect of running this command is that ‘HOST/my.fake.hostname.com’ will be added to the multi value field ’servicePrincipalName’ on my computer’s entry in Active Directory.

Jakub, one of the project members on my current project pointed me to this blog entry explaining a threading issue with Directory<K,V> in .NET: Hashtable and Dictionary thread safety considerations. I know that I earlier have written code exactly like the one in the blog entry, so this was a bit of an eye-opener.

I was at a presentation about Windows CardSpace a couple of days ago. Beautiful technology it might be, but I cannot help questioning the adoption of CardSpace in the real world. I cannot say I have ever come across any site that supports it. Have you? (If so, please let me know). On the other hand, OpenId seems to get quite a bit of momentum being supported by some of the big Internet companies out there (Yahoo!, Google, AOL to name a few).

OK, CardSpace and OpenId do not offer exactly the same solution, and are in some respects not comparable. Biggest difference would be OpenId’s reliance of passwords as authentication mechanism (which is one of the reasons for its lack of phishing attack protection), while CardSpace solves this problem using cryptography. However, there are a lot of similarities:

  • Both offer a distributed model that accepts various Identity providers (the user can choose from a number of IdPs)
  • Both address the challenge with maintaining several user account/password for different Internet services

“OpenId is no good because it isn’t secure”

When asking the presenter about the adoption of CardSpace versus the adoption of OpenId, this was his response. I think that this is a gross oversimplification that serves no other purpose than spreading FUD about security.

First of all, if OpenId is good enough for Yahoo! and the like, it will probably be good enough for 80% of the Internet sites out there. I can think of a lot more sites out there that require “less security” than Yahoo! out there, than sites  that require a higher security level.

Secondly, security is not binary (secure - not secure). There are different levels of security. Saying that one solution is secure and another one isn’t, is being ignorant towards the field of security. Basically, security (as everything else) come at a cost. In the case of CardSpace, the cost is maintenance of your cards and the corresponding public/private key infrastructure. I do not know CardSpace in detail, but a main challenge here I suspect will be exactly the same as for other public/private key based solutions: how do you bring your keys with you? For instance, if you created a card in a CardSpace on your workstation at work, how do you bring them with you when you want to log in from your home computer or from an Internet café? Having them on a USB stick would probably be a choice, but even that limits the usage quite a lot. Passwords, on the other hand, you carry with you in your head (at least, that’s the idea ;)).

On NDC a couple of days ago, I went to a session where David Chappell talked about Microsoft’s forthcoming “Oslo”. He went to great lengths to not reveal too much, as Microsoft is keeping everything very secret.  In fact, he spent more time explaining what “Oslo” is not than what it actually is.

Figuring actually what is intended to be is not easy. However, from the presentation, we know that “Oslo” is more of a “technology” or “platform” rather than a product. It will consists of the following parts:

  • The Repository. It is a storage space that has schemas that defines its data types. Actually what type of information it is supposed to or limited to, is not known. However, examples include things such as process definitions, workflow definitions, IT infrastructure information, and SLAs.
  • The Visual Editor. This is a general purpose tool that allows for editing of content in the repository. General purpose meaning that it can be used for different types of data. However, not all communication with the repository need to go through this tool. Special purpose applications or tools can connect and interact with the repository directly.
  • Extensions to Windows Workflow Foundation (WF). I am not sure exactly what kind of extensions we will see, but I can guess that it would mean extra activity components.
  • The process server. Basically, the WF does not define any host process for running workflow, and the way I figure, the process server implement such a process. It will contain a component called Lifecycle manager that can manage many process host instances (I guess for Load balancing, failover, etc.). The process server will also contain the ability to run BizTalk stuff. A question that comes to mind is whether the process server is “Biztalk for managed code” - built with the capabilities of WF and WCF? Time will show.

So what is the common denominator for all this? I am not sure. I can’t help it, but one word that keeps popping up in my mind is “governance”. Will this be “Microsoft’s tool for IT governance”?

Anyways, the time perspective of this is not known. When will this be available? All we know, is that Microsoft is planning to deliver this in three releases. Will it be in 2009?

I attended a session with Mary Poppendieck at NDC today where the topic was trashing in projects. I was a very interesting talk. One of the things that I got out of it, was the notion of churning, which basically is about two things:

  • If you have requirements churn, you are specifying requirements too early. Basically, this means that after you write the requirements, the customer changes his or her mind, and the requirements need to be changed before implementation starts.
  • If you have test and fix cycles, you are testing too late. In general, testing should be done earlier, and preferably automated

Furthermore, Poppendieck made a few references to classic queuing theory, saying that if the utiliziation of a resource is too high (saturated), the handling time will be lower and result in trashing. Hence, one should no plan for a 100% utilized project resource. The main thing is to optimize on throughput, and not on utilization.