Category: Development

05/27/09

Recently I've been called to work on an exiting project and that involved creating a basic authentication module for IIS and ASP.NET. I've already done modules in the past so that wasn't really new to me, but I took the time to go deep into that and see where that could lead us.

Basic authentication is part of the http specification and involves sending an "www-authenticate" header to the client agent (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.47), along with error code 401 (Unauthorized). In turn, the agent prompts for a username and password and replays the request, taking care to include the "Authorization" http header. That header has a value encoded in base64 (the most basic "encryption" (with quotation marks big as a house - I should rather use the term "obfuscation")). That value, once decoded, has the form "username:password", with whatever values provided by the end user. As a side-note, it should be clear that basic authentication should never occur on an unprotected channel.

Read more »

11/25/08

Permalink 07:52:26 pm, Categories: Architecture, Development

Framework makers often tend to dream of a software that can be configured in a time t lower then the time t' needed to build a solution from scratch using common 3GL tools and libraries in order to realize targeted business needs.

No software can be configured so that the cost of making it work is lower than the cost of 3GL. Corollary, any framework should only exist to serve as a guideline and guidance to good development practices, instead of trying to be a Software that builds Software. That's the essence of Omniscient's Foundation.

11/11/08

Permalink 11:06:12 am, Categories: Development

I recently had to work on an old wse3 router maintained by the team with whom I'm working at my client's. We had a timeout issue for queries that lasted for more than 100 seconds, and we had already tried all possible configurations to solve that, with no luck.
Months later, a clear mandate emerged to solved this problem (we may be asking at first why on earth we are waiting for more than 100 seconds for a request, but that's the way it's been designed and sometimes, you have to accept how things are, especially when considering that it would be more of an effort to fix the design). With this mandate in my pocket and plenty of time ahead of me, I started my investigations the way I always do it.

First, isolate the problem

I created a solution with a self-hosted server for the router itself, referencing the broken router library. Then I added a benchmark client and a benchmark server. The client would call the server, going through the router, requesting a function that could wait anytime and return any amount of data (two parameters: time to wait, and weight of data to return). That's the essence of it, make it as simple as possible, but not simpler. My buddy Rob and I evaluated that either the amount of data or the amount of time were causing the problem, so we ended up with that. After a few calls, I reproduced the problem precisely, and realized it had nothing to do with the amount of data that was returned. Also corollary, it had nothing to do with the production hardware, since I was able to reproduce the problem using only the software, on my own developer box.

Second, diagnose the problem

Now that all irrelevant overhead had been cleared from the problem, I could focus on the problem itself. Clearly, the timeout was recurrent and fix: 100 seconds. I already searched on google and did find lots of posts describing that same problem, but no solutions. So I run my project in "break on all errors" mode, got the error, and followed the callstack in the Reflector. I then discovered that the wserouter was creating a WebRequest object (or more precisely, an HttpWebRequest) to do the actual call to the remote server. Now, that object's constructor assigns the value of 100 milliseconds to a Timeout property. Getting interesting! However, it's too deeply forged into the code to allow to tweak that value before the physical forward is actually made. Following the code, I recognized the factory pattern (how important it is to be familiar with the patterns, dude! Though I recon that this one is not the most complicated ;-)) and the factories were taken from call to a static funtion called "GetSection()", and then to a property called WebRequestModules. Woooo!! Wait a minute!! Does that mean I can configure my own WebRequest factory, and create it with a custom Timeout value? A small research confirmed that. So, here's the configuration I came up with:

<system.net>
    <webRequestModules>
        <clear />
        <add prefix="http" type="PerimeterServiceRouter.ConfigurableHttpRequestCreator, PerimeterServiceRouter" />
        <add prefix="https" type="PerimeterServiceRouter.ConfigurableHttpRequestCreator, PerimeterServiceRouter" />
    </webRequestModules>
</system.net>

As you can see, I created a new type called ConfigurableHttpRequestCreator, and I was able to put a breakpoint into it and it would be hit... Problem diagnosed!

Third, design the solution

That's the easy part, at least in this case. All I had to do was to return an instance of HttpWebRequest, with its freaking timeout being more than 100 seconds, preferably reading the value from the config file. So I wrote "return new HttpWebRequest()", rebuilt, and boom! Not working... Yah... All the available constructors are internal constructors. Should have seen that before. Unavailable. Unreachable. Damn. (that reminds me this nice post from Eric Lipert). But you see, that's a reason why .NET is so nice; the language itself, the mechanics of your software, even the very base of object-oriented containment, all that can be manipulated at run-time in terms of types, methods and properties. Then, an internal ctor suddenly becomes an object of type Constructor with an "internal" flag on it. And the best part: you can invoke it, meaning that you shift the execution into the very code of that Constructor object, and handle anything returned by this execution. Playing around with the classes themselves as concrete entities, instead of the semantic meaning of it and object instances of it, that's what reflection is all about baby! Here's what I did:

public WebRequest Create(Uri uri)
{
    HttpWebRequest r;
    Type t = typeof(HttpWebRequest);
    ConstructorInfo ctor = t.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(Uri), typeof(ServicePoint) }, null);
    r = (HttpWebRequest)ctor.Invoke(new object[] { uri, null });
    r.Timeout = GetTimeout();
    return r;
}

Where GetTimeout reads the value from the config file. I'm now waiting for the QA to find any regression issue caused by that code, but preliminary tests in my self-contained environment are quite positive - or negative, depending on how you see it - and the timeout is gone.

10/31/08

Permalink 09:46:27 am, Categories: Development

In the process of developing omni-timetracker, a small time tracking software built on top of Foundation for the purpose of demonstrating real life use of the framework, I've got to a point where I needed a real web server. That is, I'm a strong advocate of TDD (test driven development), dependency injection and inversion of control. That allowed us to develop an almost complete first iteration without even using a web server (omni-timetracker consists of a client application connecting to a central repository with WCF).

As I said, I got to the point where I had to "seal off the loop", like we say in French, and plug in a real web server. So I went and created a web application, and changed the web.config file to use username/password authentication over SSL. I particularly wanted to use the Visual Studio Development Server, because using IIS adds a layer of complexity, and I hate adding layers of complexity during development. Some of you might argue that using SSL and username/password authentication also adds a layer of complexity, and I will have to agree; however, I consider http and https to be different protocols, even if the latter is "http over SSL", and the production target is really https. And frankly, once it's set up, it's really transparent, contrary to using IIS that may be unavailable on certain development machines, suddenly shut down, and so on. For your sake, I'm including here what it takes to sit a wcf service behind https:

1- Declare a binding that uses Transport security (SSL), along with message (SOAP) credentials; with each message, the service expects to find a username and a password in the SOAP envelop.

<bindings>
    <basicHttpBinding>
        <binding name="usernamePasswordBinding">
            <security mode="TransportWithMessageCredential">
                <message clientCredentialType="UserName"/>
            </security>
        </binding>
    </basicHttpBinding>
</bindings>

2- Create a root authority certificate, if you don't already have one.

makecert -sv SignRoot.pvk -cy authority -r signroot.cer -a sha1 -n "CN=Dev Certification Authority" -ss my -sr localmachine

3- Create a development certificate signed by the authority created at step 2:

makecert -iv SignRoot.pvk -ic signroot.cer -cy end -pe -n CN="localhost" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

4- Bind a port to that certificate, allowing https on that port. The "certhash" value is the hash of the certificate created at 3. Note that this is for Vista.

netsh http add sslcert ipport=0.0.0.0:4748 certhash=fe11ed089562b785df77c7e8ef391445d70705d6 appid={00112233-4455-6677-8899-AABBCCDDEEFF}

Ok, so let's come back to the subject. I've done all that, and with a smile, I pressed F5 on my web project. And then, Boom! Got this error: "The protocol 'https' is not supported". Wow. I've been using the development server for years since .Net 1.0, and what? That's the first time I realize that it doesn't support https? Apparently. But that's not inherently bad. I can use the exact same config, and use it in an even simpler server: a simple self-hosted server, using wcf's "host" class.

September 2010
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    

Here on this blog you'll find continuous thoughts and information about Omniscient's Foundation framework.

Search

The requested Blog doesn't exist any more!

XML Feeds

multiblog