What Lao Tse thinks of TDD

September 22, 2008

Summer is tumbling into fall and apparently it has stirred the technology muses because the last few days seem to have invoked a collective urge to wax philosophical about development practices in the small corner of the blogosphere that I follow. Jimmy Bogard started the ball rolling comparing  TDD to living a more healthy lifestyle, Ayende expressed his understanding of the true, sensitive core of Agile, Kyle Bailey wondered aloud if the ALT.NET horse is pulling too far ahead of the cart, Rod Cottingham of ReadWriteWeb briefly awakened from his Social Media junky trance to wonder if there wasn’t more to life before pushing in the plunger once more and sinking back into the carpet, and the usual band of roaming ALT.NET monks came to the vigorous defense of TDD, which was apparently issued a challenge on the ALT.NET mailing list. All this in addition to the usual, melodious gospel music emanating from Los Techies and CodeBetter.com.

For me, it was quite a treat. In addition to being a rabid technologist, I am also an armchair philosopher, so this kind of material is food for me. I will have more to say about the enormous question so fleetingly put in Rod Cottingham’s post another time, but today I want to think a little bit about the flurry of emotion regarding TDD, because while the passion its practitioners exhibit for the methodology is in itself compelling I don’t feel they are otherwise expressing its true value very effectively to those who I presume they are speaking, which is to say to me, the layman and the novice.

I myself have only just begun to experiment with Test Driven Development in particular and Agile methodologies in general, along with the rest of my small and equally inexperienced team. Speaking from such a demographic, I can confirm that TDD is a difficult discipline to become comfortable with. Speaking from a project management perspective, I can also confirm that starting from standing still getting up to cruising speed with TDD is, at least superficially, expensive from a productivity standpoint. I believe every member of my team is both talented and passionate about the mystical process of creating quality software, but taking up TDD is nevertheless quite challenging.

Even so, our limited and amateurish experience with TDD so far has deeply impressed all of us, so much so that the productivity cost of the learning curve has never once felt like anything but an investment. To wonder whether or not the cost is worth the benefit is perplexing to me, I can’t imagine having that emotion. Maybe I’m spoiled by the talent and passion of my colleagues, maybe if you find yourself alone amongst a crew of 9 – 5 clock punchers the row is much tougher to hoe, but you don’t have to scratch very deep into the surface of TDD to find its extraordinary value, even though it does require constant discipline (which often falters, by the way) to continue using it, at least at the early stages we are in.

What is this great value that outweighs the effort?

Well, there isn’t any point in my spelling out the tangible, objective benefits. That the TDD monks express quite well, and anyway I’m a layman, so I wouldn’t be able to do it effectively in any case. What I find strange, though, is how TDD seems to always be discussed outside of its Agile context – as if it were a side dish you could have with any kind of meal without it losing any of its overall value. Rather, I see TDD as the chorus to the Agile song – it may be beautiful to sing in isolation, but it grew out of, and belongs to, a larger melody, and to really understand its value an experience and understanding of the larger context is of the utmost importance.

The larger context? Iterative, outside in development, of course. Agile is a highly iterative development methodology that focuses first on the need and then on the implementation in short repetitive cycles. It has the potential to transform software development from a giant thought experiment in which we attempt to construct  tightly fitting, complicated wardrobes of clothes for our customers by asking them to describe the shapes of their bodies in perfect detail and list up front every social function they will ever need to attend, to one in which we take small, precise measurements, create one article of clothing at a time, try it on the customer, have them spin in front the mirror, and make adjustments accordingly: to the patterns, to the materials, to our tools and our processes.

The universe itself is rhythmic, cyclical and defined by nothing if not constant change, and so therefore are our lives, our work and the needs of our businesses. Software, unlike other more traditional engineering disciplines that deal with physical space and universal themes, must keep constant pace with the rhythm and change of human activity for it to be useful. Not only that, but the complex needs software aims to serve cannot simply be measured, like a plot of land or the gorge a bridge must cross, it must intersect usefully with myriad human minds rather than relatively predictable physical material, and the human mind is famous for not knowing itself very well.

So Agile attempts to adjust for this by addressing human need in an interactive way – assess the general outline of the need first, build a little something, see how it fits, make adjustments here and there, fill the general shape of the need, add the detail in layers as it is discovered. It brings to my mind an image of a potters wheel – the clay spins always, an iteration at a time, you shape a vessel first with your fingers, relying as much on tactile feedback as you do your logical understanding. Then you apply detail, little by little, and when it is finished you can fire it in the kiln and paint it, but not before. If you build the detail too soon, it will quickly get rubbed away as the true need emerges, or worse, it will remain because you’ve put the thing in the kiln too soon, but it won’t be appropriate to the piece you’re creating, so you cover it up with fresh clay and fire it again, and you end up with something structurally unsound, or ugly, or altogether useless.

What does all this melodrama have to do with TDD? TDD is your fingers in the clay. Code is clay, after all, not gears and pistons and fittings, it has constraints, of course, but is largely pliable imagination. TDD is what finds an ideal shape for the code that is elegant, appropriate and capable of realizing the emerging and actual (not theoretical) needs of your customers as they are incrementally uncovered by the larger Agile process. TDD feels out, does not deduce via thought experiment, an appropriate API. This has been my takeaway from our limited experiments with the methodology, at any rate. TDD as the smallest possible step, the smallest possible rhythm, red-green-refactor, red-green-refactor, you rely predominantly on a sense of practical aesthetic, an ability of the mind to find a natural shape for things, a process that is usually expressed in terms of “reducing friction” by the community of vocal practitioners. Of course this is a logical process too, of course, not just an artistic one, there are general rules and guidelines, it is a strange coupling of mathematics and logic with imagination and creativity and pseudo-tactile feedback. Your mind is clicking along in a scientific way, but a larger part of the brain is enlisted to participate, a part that, as engineers, we too often discount, more than just the cold eye of logic with too little information at its disposal and too high an opinion of itself. In the end its all very Taoist :) The Taoist butcher, as you may know, never has to sharpen his knives because he always cuts his meat precisely along the grain – he isn’t cutting at all, actually, but merely separating the material along its natural seams. TDD aims to find those seams in the seemingly solid material of a programming language as it applied to a complex human problem and the result is often of very high quality, both aesthetically and functionally, and the secret is both qualities are the same quality when approached in this way.

Anyway, that was a lot of grandiose hoo ha, and I’d be surprised if any of you left brained technologists have made it this far. Whether or not I’ve made any sense, my main point is that when practitioners are always saying TDD is about design and not about testing, I think this is in essence what they mean. Even if it isn’t, that distinction – the distinction between “design” and “testing” is tragically under-emphasized, or at least under-explained, and that distinction, in my mind, is the crux of the whole matter, is the first thing that should be said about TDD to anyone who is interested in listening. In that context, the question of “is it worth the cost” is almost nonsensical.

If by some miracle you have read this far, I’d love to hear what you think – what is your understanding of TDD? Or, do I simply need to lay off the hookah?

 

The Butcher

There was once a butcher who was carving a joint of meat for a customer who had been coming for many years.

 

“Pardon me,” the customer asked, “But isn’t that the same knife you had last year? Do you need to sharpen it often?”

“It’s the same knife I’ve had for the last 17 years,” the butcher replied, “And I haven’t had to sharpen it even once. For, when I cut the meat, I allow the knife to find its own way through the flesh without effort or stress.

“And when I come to a tricky bit with lots of cartilage, I just slow down and allow the mystery to solve itself and in no time the meat falls right off the blade.”

If there’s one thing the Taoists love, it’s getting things done without any effort at all

 

Replace “Toaist” with “Programmer” in that last sentence and you have the essence of our industry :)

Rule Based Access Control using an Expression Evaluator

September 17, 2008

I’ve written previously about “claims based authorization,” and how I believe it will eventually become a ubiquitous approach to identity management as the world of online digital identity reinvents itself in order to avoid implosion. If you aren’t familiar with the concept of claims based identity, I recommend checking out the post linked above or following some of the links from this post.  If you just want to examine the sample code for this post, it is here.

In this post I’m interested in how a set of claims presented by a user when making a service call can be evaluated against specific authorization rules to determine whether or not the user has access to the requested resource.

The details of how a user is associated with such claims, how they are secured, and how claims are embedded inside calls to your service are beyond the scope of this post, but the links listed above should provide a place to put the tip of that chisel. For the purposes of this post I will assume that claims are presented via a list of IClaim objects, and an IClaim is nothing but a Name/Value pair – IList<IClaim>. This is very similar to how Micrisofts new Zermatt Identity Framework represents claims, and this was intentional as I believe that Zermatt is probably the future of Identity Management on the .NET platform.

So then, given IList<IClaim> claims, how can we make rational authorization decisions, such as “I only want users who are in the Premium Members role and whose age is older than 21 to access this (probably seedy) service method.” One obvious, simple approach would be to evaluate the claims programmatically. Some simple extension methods can make this much easier:

public static class ClaimsExtensions
{
   public static T GetClaimValue<t>(this IList<iclaim> claims, string claimType)
   {
       foreach (IClaim claim in claims)
       {
           if (String.Compare(claim.ClaimType, claimType, true) == 0)
           {
               return TypeNormalizer.EnsureType<t>(claim.Value, default(T));
           }
       }
       return default(T);
   }

   public static bool ClaimEqualsAny(this IList<iclaim> claims, string claimType, string claimValue)
   {
       foreach (IClaim claim in claims)
       {
           if (String.Compare(claim.ClaimType, claimType, true) == 0)
           {
               if (claim.Value.Equals(claimValue, StringComparison.InvariantCultureIgnoreCase))
                   return true;
           }
       }
       return false;
   }

   public static bool EvaluateClaim<t>(this IList<iclaim> claims, string claimType, Func<t , bool> eval)
   {
       var claimValue = claims.GetClaimValue</t><t>(claimType);
       return eval(claimValue);
   }
}

Then, from within a method that needs protecting, you can easily do something like this:

public void MyServiceMethod()
{
    if (CurrentUser.Claims.EvaluateClaim<int>(CustomClaimTypes.AgeInYears,age => age < 21) ||
        CurrentUser.Claims.ClaimEqualsAny(CustomClaimTypes.Role,"Premium User") == false)
    {
	//Whatever you do when someone isn't authorized. Throw a not authorized exception? Return a fault code?
    }

    //Implement your service method here, your user is old enough and has paid their money
}

If you were clever, you could probably figure out a way to use LINQ expressions to make the syntax even cleaner. This is all good and well, but it has at least one major problem – authorization rules are probably likely to change far more frequently than your application code. Even worse, you may wish your power users to be able to manage their own authorization rules for certain kinds of access or for named permissions. Using the technique described above, any change to any authorization rule will require you compile and deploy your application.

One common solution to conundrums such as these is to use a DSL (Domain Specific Language). And while you certainly could write a custom DSL to implement your authorization rules, authorization rules have an interesting characteristic: they always resolve to a discrete value, a true or a false. They are simply boolean expressions.

There are a number of Expression Evaluators available from the open source community that will fit the bill perfectly. An Expression Evaluator will allow you to specify your authorization rules as simple strings, which means they can be stored in a configuration file or a database or some other persistent store and modified and run-time as needed. They are also serializable by definition and can easily be requested by and cached at the user interface to allow the user interface to use the same authorization logic  to render itself appropriately with respect to the permissions of the currently logged in user that the server will use to authorize access to its API without (necessarily) having any code in common other than a reference to the same expression evaluator library.

In this example I will be using Simple Expression Evaluator available on Codeplex. I chose this library purely out of nepotism, because I wrote it, but you should be able to use any expression evaluator that catches your fancy. A number of options for .NET are listed here.

Using an Simple Expression Evaluator we could rewrite the above authorization rule like this:

AgeInYears >= 21 and MatchesAny(Role = "Premium User")

In the sample project I added a custom function, IsInRole, allowing this syntax:

AgeInYears >= 21 and IsInRole("Premium User")

To make this happen, Simple Expression Evaluator will need a little help in interpreting claim names. The main reason behind this is that claims are usually represented by a URI, such as http://thefreakparade.com/claims/role, but accessed through code using string constants, such as

public static class CustomClaimTypes
{
     public const string Role = "http://thefreakparade.com/claims/role";
     //...more...
}

and therefore accessed in code like this:

var claim = new Claim(CustomClaimTypes.AgeInYears,43);

The expression evaluator will interperet something like AgeInYears to be a variable, and the name AgeInYears won’t naturally correspond to anything, because it’s really just a property name, the real claim is represented by a URI that would be far too ugly to stick in an expression. The solution is to give the expression evaluator a little help when evaluating variables, like so:

public bool Authorize(IList<iclaim> claims,string authExpression)
{
    var context = new ExpressionContext(claims);

    context.ResolveUnknownVariable +=
        (sender, args) =>
            {
               args.VariableValue =
                 claims.GetClaimValue(_claimAliases[args.VariableName]);

            };

    context.ResolveMissingFunction +=
        (sender, args) =>
            {
                if (args.FunctionName.Equals("IsInRole",StringComparison.OrdinalIgnoreCase))
                {
                    args.Function = (funcArgs) => IsInRole(claims,funcArgs);
                }
            };

    return ExpressionEvaluator.EvaluateExpression(authExpression,context);    

}

This method was modified a little from the actual sample to the purpose of clarity, but the general idea is the same. Also demonstrated is the technique required to add an IsInRole method to the expression language. The actual implementation of the IsInRole functionality is implemented off screen, see the sample for the actual code. This method also relies on a hashtable called _claimAliases being pre-populated with a mapping between the URI of a claim type and the friendly name the expression language will use. In the sample app, I simply used reflection to load the alias table with a mapping between the field name of each const and the actual URI.

Now, if you simple use the expression evaluator an call Authorize from within your service methods, like this:

public void MyServiceMethod()
{
    if (AuthorizationHelper.Authorize(
           CurrentUser.Claims,"AgeInYears >= 21 and IsInRole('Premium User')" == false)
    {
	//Whatever you do when someone isn't authorized. Throw a not authorized exception? Return a fault code?
    }

    //Implement your service method here, your user is old enough and has paid their money
}

Then all we added with the dynamic expression was complexity – your rules are still defined inline in your code. What you really want is a syntax like this:

public void MyServiceMethod()
{
    if (AuthorizationManager.Authorize(CurrentUser.Claims,Permissions.CanAccessServiceMethod) == false)
    {
        //no access
    }
    //service code
}

Where Permissions.CanAccessServiceMethod will key into a persistent authorization rule store such as a config file or database, so that the rule expressions themselves can be dynamically loaded at runtime and therefore modified outside of the code. The sample application takes advantage of a very simplified implementation of the Repository pattern and introduces an IAuthorizationRuleRepository to solve that issue. If you were really, really smart you could get to a syntax like this without much extra effort. Note this sample application does not quite go this far, but it shouldn’t be a stretch for you get there yourself if you care to:

[RequiresPermission(Permissions.CanAccessServiceMethod)]
public void MyServiceMethod()
{
    //service code
}

The only caveat with an attribute based approach is that access to your protected method is all or nothing. You can’t return a set of records filtered one way when one permission level is present, and another for a lower level of permission. But nothing would prevent you from mixing an attribute based approach with an inline-code based approach as appropriate.

Finally, here is a sample of the actual authorization syntax as implemented by the Identity at Rest sample application:

public List<monkey> ListAllMonkeys()
{
    //Only administrators can list all monkeys.
    //Everyone else can just list shaved monkeys.
    if (AuthorizeFor(
            Permissions.MonkeyShavingService.CanViewUnshavedMonkeys) == false)
    {
        return ListMonkeysByStatus(MonkeyStatus.ShavedClean.ToString());
    }

    return _monkeys;
}

And that’s about it. If you’ve made it this far, your very well aware that this post is describing a general approach to claims based authorization using an expression oriented DSL – the code samples listed here aren’t detailed enough to get you from point A to point B in an actual implementation. However, the included sample application, which is an evolution of the Identity At Rest sample application provided for this post, does provide an end to end application that fully implements the concepts discussed here. The sample comes with a “smart client” Winforms application that uses WCF to communicate with a remote  REST based API. All API calls are secured using the above described techniques.

I would be the last one to suggest that this approach is a “best practice” in managing claims based authorization, but it made sense to us and seems to work pretty well so far.  As always, I’d love to hear about any other approaches that you may be using.

CrapOverflow? Really? Oooooooook then… (Or, the fallacy of elitism)

September 14, 2008

I noticed an incoming link to this blog today coming from a site called crapoverflow.com, and since I know you’ll never guess it on your own I’ll just come out and tell you that it is a play on the name of the new programming Q + A web site stackoverflow.com (which I posted about a while back ago).

The crapoverflow.com web site seems to be just one page. In addition to the razor sharp wit of the name itself, crapoverflow sports a simply side splitting logo that lampoons the stackoverflow logo by making it look like the “stack” might be “crap” coming out of a toilet. Although my description should be vivid enough to elicit an HD quality image in your minds eye, I’ll paste the sites header into the post for those of you lacking imagination:

logo
Ask programming questions. Get answers… just not good ones.
Stack Overflow is by programmers, for mediocre programmers — regardless of platform, or language.
Jump in and share your lack of software engineering expertise! No accuracy or evidence is required. Ever.

The rest of the page is quotes from blog reviews, like the one from my (mostly positive) write up. All the quotes say something un-complimentary about stackoverflow.com. Before I continue, though, I would like to emphasize a few things: I am not writing this to defend stackoverflow.com from this  odd attack. I have little interest in stackoverflow.com personally and could care less about that  Also, I am not writing this to condemn the utterly juvenile author of crapoverflow.com for being utterly juvenile. Whoever took the time to register a domain name, create a logo and dig up any possible hint of a negative mention of stackoverflow.com was clearly slighted in a personal way by either the community that inhabits stackoverflow.com or Jeff Atwood or Joel Spolskey or a combination thereof. While I am tempted to say “time to grow up you sad, humiliated creature” I kind of think this kind of outlet is preferable to  showing up at the stackoverflow.com offices with a semi-automatic and a backpack full of pipe bombs.

imageSo what is my point? A noble one: I will rise to the defense of the poor, downtrodden mediocrity. The “mediocre programmer” gets a lot of hate mail these  days, and it makes my skin crawl every time I see it. First of all, by definition, most programmers are mediocre. Even if most programmers were capable of hacking into NASA and re-programming the space shuttle to swing through a McDonalds drive through and bring them a happy meal, they would still be mediocre because most programmers must be mediocre, mathematics and the English language are very insistent in that regard. So mathematics and the English language being what they are, when a community develops on the Internet and begins to thrive, and it turns out that this community is made up of mostly *gasp* mediocre programmers, whose business is it to issue condemnations?

Closet Mediocrity

First, I’ve yet to meet the programmer who would classify themselves as mediocre. And yet statistically most of us are in those ranks. That means more than a few mediocre programmers are erroneously counting themselves among the elite. So unless you have some sort of proof (beyond the cajoling whisperings of your own ego) that your light shines brighter than that of the status quo, you better keep your yap shut on the matter.

Community is Community

If you start a Q + A site and the experts don’t show up, should the rest then lay down and die? Or rend their tunics and make sacrificial offerings hoping they will show up after all? If most of us are mediocre by definition, and we get together to help one another out as best we can, who is the victim? Let’s have a thought experiment shall we … let’s say I asked for some help and I received some advice and the advice turned out to be mediocre. Even so, despite its impurity, it helped me through my problem. It wasn’t the way an expert would have solved the problem, to be sure, but the expert never showed up to gift me with her genius, and yet things turned out OK in the end anyway. The solution to my problem, thanks to the mediocre chap that answered my mediocre question, was squarely mediocre. Actually since I myself am mediocre the solution fit in nicely with the rest of my mediocre project. It doesn’t strike terror into my heart to contemplate such a scenario, nor does it make me snigger condescendingly and count my lucky stars I’m not mediocre. It makes me glad such communities exist, because if the elite programmers are too busy writing software to lend a hand they may as well not exist, and yet we must march on, mediocre or not.

Actually, We’re All Mediocre

Whoever you are, you too are mediocre. Even if your genius in matters of programming is unparalleled then in your personal relationships, or your spiritual life, or in the sack, whatever, mediocrity has set a place for you at its table. But let’s reel it in a little and assume you’re not one of the half dozen most brilliant programmers in the world – in that case, I can make you an utterly mediocre programmer no matter who you are just by choosing the set of programmers in which you are to be counted. So mediocrity then is entirely relative, and therefore an illusion. To look down your nose at the man treading water down stream from you is to ignore the countless others who have already passed you by a mile. If the fellow is struggling and it distresses you, lend a hand. If you can’t be bothered, then don’t, he’ll do just fine. But it is vulgar and absurd to shout an insult at him, or to preach to others that its people like him who are keeping us from reaching our full potential.

Is this the part where you say “Amen” and hand out the little crackers?

Sooooo…thats it really. To be fair, the vast majority of people in the programming communites I haunt that I would consider to be “elite” expend vast amounts of effort feeding the community the fruits of their knowledge and insight, and usually with a reasonable amount of humility. It’s even a little awe inspiring sometimes. It is usually the false-prophet, the average Joe that fancies himself a rock star, that is likely to make some pointless attack on the imaginary ranks of the mediocre (what I like to call  “spitting on Mort”). Even so, each time someone does this it leaks a little poison in the water supply we all depend on for survival, even though it is almost always unintentional. So if I had a particular point, I guess it would be to try to keep a few things in mind, especially when you feel the urge to jump onto a soap box and start talking down to people:

1. We’re all doing the best we can. Really. What else could we do?

2. Everybody has a right to lend a helping hand, to ask for help, to discuss a technology, to offer an opinion, to participate. If we all had to be experts and 100% sure of what we say in order to participate in the community you’d hear nothing but crickets, I guarantee it. If you encounter an error someone has made through inexperience, be generous and correct it, don’t complain about it, it makes you look ugly and as a result you won’t get laid without having to pay for it.

3. However smart you may be you’re a bumbling idiot compared to someone. Just keep that in mind and not only will you be more pleasant to be around but you’ll be more useful to the world and you’ll learn faster as well.

image

Amen. Here is the body, and here is the blood. See you next Sunday.

A Response to "On Passion"

September 6, 2008

Jimmy Bogard recently gave an interesting sermon on the topic of passion in software development. I always enjoy posts like this. While I love the technical insights that flow like a river from the software development community, there is an under-served but very real need to pan out from time to time and reflect on the larger experience.

Software developers are an interesting breed – on the one hand we are technicians and engineers, a left-brained, puzzle solving people, and yet the medium in which we work is almost pure imagination. We sculpt more than we build, and yet we focus so intently on the mechanics and the techniques that I think we have a tendency to de-emphasize the broader creative process and the very human aspects of what we are really doing all day with these wonderful machines. So a discussion of passion, and particularly an encouragement to extend our passion beyond the realm of simply solving interesting logical puzzles, is refreshing and needed.

In his post Jimmy calls out the tendency of software developers to practice in an unbalanced way, to practice in a way that is obsessively, even selfishly focused on the self-gratifying enjoyment of technology for its own sake. If we were a self contained community of artists then it would be alright for us to practice in such a narrow minded way, we could revel in our technology with reckless abandon. But of course that is not the case. As a profession we are simply an organ in a much larger organism and we depend on the health and prosperity of the organism for our survival as much as it depends on us, despite our legendary hubris.

Observing this, Jimmy suggests that our ultimate success relies on our being as passionate about the domains we serve as we are about the software itself. He separates passion for “our craft” from passion for “the domain.” While I wholeheartedly agree with the underlying principal of what he is saying, I think his separating “the domain” from “the craft” and demanding software developers apply passion in equal measures to both does a great disservice to “the craft” and would be impossible to achieve for most of us in any event.

Any programmer reading Jimmy’s blog probably has little if any passion to spare. Software practitioners of an ilk that read blogs like those found at Los Techies are not looking for new outlets through which to direct our energies; we are already giving all we can (and often more) to “our craft.” Asking us to become passionate about the domains we serve is like asking someone running a marathon to pull a rickshaw full of tourists while they’re at it. Is it possible? Maybe. But it’s also absurd.

However, I certainly don’t think it is healthy, sustainable or ethical for us to fornicate with our technology at the expense of our patrons. I agree with Jimmy that such an approach to software development cannot end in success. I do, however, believe that a more appropriate mental framework would be to expand the scope of what we mean by “our craft” instead of relegating “our craft” to the realm of technology and layering on the additional responsibility of “the domain.” Most of us cannot be passionate about “the domain” anyway – if we could, we would have different careers. But we can, and we should, be passionate about shaping software that best contributes to the health and prosperity of the businesses in which we operate. This may seem similar to being passionate about “the domain”, but it is not at all the same thing. We should be passionate about our domain, but our domain is not technology any more than an artists domain is paint. An artist obsessed with paint may create some very beautiful colors, but uninteresting paintings. No, our domain is software, and software is about nothing if it isn’t about people. So we do have to understand the domains we serve through and through, we do have to place the user experience above technological self-gratification, but we should not dilute our passion by attempting to extend it beyond creating delightful, functional software.

In the end I think Mr. Bogard and I are saying the same thing – I don’t think he actually meant to suggest that we truly become passionate about, say, medical billing or real time currency trading, or whatever world you happen to be working in, but that we become passionate not just about technology but also (and predominantly) about sculpting software systems that enable those that are passionate about those things to achieve ever increasing levels performance and creativity. And I couldn’t agree more.

Flowing Identity from a Client to a Service when using RESTful WCF Part 2 – A Solution

September 1, 2008

This post will describe a technique to transparently insert a custom HTTP header into all requests generated by a WCF REST proxy, as well as a technique to extract that HTTP header from the request at the service for the purpose of flowing the digital identity of an authenticated user from a REST client to a REST service. In this case, digital identity is represented by an authorization token, which is just a string. You can read a detailed description of the problem in Part 1 of this post. A complete sample project containing the full source code of the solution is on CodePlex.

The basic idea is to insert a custom action into the WCF message pipeline that will extract a security token representing the identity of the currently logged in user and add the value of that token (just a string) to the outgoing API call (an HTTP request) by way of a custom HTTP header. Once the request is received by the service, a custom action inserted into the receive pipeline checks for the custom header and, upon finding it, de-serializes the identity token and uses the claims contained within it to set an appropriate security context (in this case by setting Thread.CurrentPrincipal).

Setting a Custom HTTP Header – The Easy Way

On the client side, I am making the assumption that a user has been authenticated somehow, is associated with a set of claims, and that a representation of the user along with her claims can be found at Thread.CurrentPrincipal. In anticipation of using Microsoft’s new Zermatt Identity framework, which introduces IClaimsPrincipal and IClaimsIdentity, we implemented our own versions of these interfaces. They will eventually be replaced by the Zermatt types once we start integrating Zermatt into our application. IClaimsPrincipal maintains a reference to IClaimsIdentity, which has a property of type IList<IClaim> that represents all the authorization relevant attributes of a user. Please see this post for a discussion of claims based identity management. The interface IClaim is pretty much just a name value pair.

Adding a custom header to a request is trivial if you add the header in the same scope as the service call made on the proxy. You can just wrap the entire call in an OperationContextScope using statement, and use the Headers property of WebOperationContext.Current:

using (var factory = new WebChannelFactory<imyservice>())
{
  IMyService proxy = factory.CreateChannel();
  using (new OperationContextScope((IClientChannel) proxy))
  {
    WebOperationContext.Current.OutgoingRequest.Headers.Add('x-mycompany-auth',
                                                            'tokenString');
    proxy.DoItToIt();
  }
}

That technique works, and would probably be just fine if you only needed to add the authorization token to a few select calls. However, in our scenario, we want to add the token to *every* call, so wrapping each API call with all that scoping garbage isn’t going to cut it. It’s ugly and about as un-DRY as it gets.

Extending WCF – The Transparent Way

The solution, of course, is to take advantage of the WCF extensibility points available to both the client and the server. We want to choose spots in the messaging pipelines as close to the actual delivery/receipt of the message as possible.That would be the the Message Inspection phase on the client and the Operation Context Initialization phase on the server.

WCF can be made to jump through our hoops by following these steps:

On the client side we need to

1. Define the MessageInspector

2. Create a behavior to register the MessageInspector

3. Install the behavior on the channel factory.

On the service side we need to

4. Define a OperationContextInitializer

5. Create a behavior to register the extension

6. Apply the behavior to the service.

The end result is that Thread.CurrentPrincipal on the service side will always reference an IClaimsPrincipal with the same claims associated with the Thread.CurrentPrincipal on the service consumer, and we can test those claims to authorize access, as demonstrated in

7. Use.

1. The MessageInspector

 public class ClientAuthMessageInspector : IClientMessageInspector
 {
        #region IClientMessageInspector Members

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            //Get the HttpRequestMessage property from the Message
            var httpRequest =
                request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;

            //Make sure we have a valid property, or create one
            if (httpRequest == null)
            {
                httpRequest = new HttpRequestMessageProperty();
                request.Properties.Add(HttpRequestMessageProperty.Name, httpRequest);
            }

            //Add your token to the header. Simple as that.
            //In real life, we injected an ITokenProvider using an IoC,
            //instead of using static methods directly, but that was
            //overkill for a sample.
            httpRequest.Headers.Add(AuthenticationHelper.AUTH_TOKEN_HEADER_NAME,
                                    AuthenticationHelper.GetAuthTokenForCurrentUser());

            return null;
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            //nop
        }

        #endregion
 }

2. The Behavior

public class ClientAuthBehavior : IEndpointBehavior
{
        private readonly ClientAuthMessageInspector _messageInspector;

        public ClientAuthBehavior(ClientAuthMessageInspector messageInspector)
        {
            _messageInspector = messageInspector;
        }

        #region IEndpointBehavior Members

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            //Install the message inspector
            clientRuntime.MessageInspectors.Add(_messageInspector);
        }

        //no-op method implementations elided for clarity.
	//See the sample project for the complete
	//code listing.

        #endregion
}

3. Apply

 private void InitializeChannelFactory()
 {
    _channelFactory = new WebChannelFactory<imonkeyshavingservice>("shavingService");
    _channelFactory.Endpoint.Behaviors.Add(new ClientAuthBehavior());
 }

4. On the Service Side…OperationContextInitializer

 public class ClaimsAuthContextInitializer : ICallContextInitializer
 {
     #region ICallContextInitializer Members
      public Object BeforeInvoke(InstanceContext instanceContext,
                                IClientChannel channel,
                                Message message)
     {
         DetectCurrentUser();
         return null;
     }

     public void AfterInvoke(Object correlationState)
     {
     }
     #endregion

     private static void DetectCurrentUser()
     {
         if (WebOperationContext.Current == null)
             throw new InvalidOperationException("Only HTTP web requests are supported for this version of the API");

          string authToken = WebOperationContext.Current
             .IncomingRequest
             .Headers[AuthenticationHelper.AUTH_TOKEN_HEADER_NAME];

         if (AuthenticationHelper.SetCurrentUserFromAuthToken(authToken) == false)
         {
             WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
                throw new UnauthorizedAccessException(
                 "No authentication token was found in the headers of the current request.");
         }
    }
 }

5. The Behavior

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class ClaimsAuthServiceBehavior : Attribute, IServiceBehavior
    {
        #region IServiceBehavior Members

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
                                         Collection<serviceendpoint> endpoints,
                                         BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                var cd = cdb as ChannelDispatcher;

                if (cd != null)
                {
                    foreach (EndpointDispatcher ed in cd.Endpoints)
                    {

                        foreach (var dispatchOperation in
                            ed.DispatchRuntime.Operations)
                        {
                            dispatchOperation.CallContextInitializers
                                .Add(new ClaimsAuthContextInitializer());
                        }

                    }
                }
            }
        }

        #endregion

6. Apply

 static void Main(string[] args)
 {
      _host = new WebServiceHost(typeof(MonkeyShavingService),
                                 new Uri("http://localhost:8000"));

      _host.Description.Behaviors.Add(new ClaimsAuthServiceBehavior());

       var binding = new WebHttpBinding();
       _host.AddServiceEndpoint(typeof(IMonkeyShavingService), binding, "");

       _host.Open();

       Console.WriteLine("Press any key to exit.");
       Console.ReadKey();
 }

7. Last but not least, Use (this is a sample service method that restricts access to certain users)

 public Monkey PutMonkeyInShaver(Monkey monkey)
 {
      //Only authenticated users can add monkeys to the shaver
      if (CurrentUser == null)
      {
       SetStatusCode(HttpStatusCode.Forbidden,
                     "Only authenticated users can put monkeys in the shaver.");
       return null;
      }

      _monkeys.Add(monkey);
      ShaveMonkey(monkey);
      return monkey;
 }

 private IClaimsPrincipal CurrentUser
 {
     get { return Thread.CurrentPrincipal as IClaimsPrincipal; }
 }

It works, but…

Our ultimate solution does not extend or take advantage of any of the claims based security features built into WCF. While it may be possible to do so, it wasn’t immediately obvious to us how to go about it, so the solution presented here handles authorization out of band from the built in WCF authorization mechanisms.

As you may have guessed, I am NOT a WCF expert. That means that the approach outlined here could very well be a cheap hack for a problem solvable in a much more elegant way. If by some chance you happen across this post and know that to be the case, I’d love to hear your thoughts on the subject :) I wasn’t able to find any guidance during my own research that hinted at a more appropriate approach to solving this problem, but that certainly doesn’t mean one doesn’t exist.

About the Sample Application

The sample application can be downloaded here and includes a complete, end to end REST API implemented in WCF. It includes separate DLL’s to represent the Service, the Contracts, the Client, a Service Host and a Utility DLL that contains shared authentication and authorization code. To get the most from the sample you should run the Service Consumer project, a Windows Forms application that allows you to invoke various operations of the API while impersonating users with various roles. In addition to demonstrating a possible approach to flowing a claims-based security token through a REST API, the sample demonstrates a fully functional, RESTful WCF service, which may be useful to you in its own right.

Here is a screen shot of the sample Windows Forms service client:

What’s Next

In the future I will be enhancing the sample to demonstrate our approach to defining authorization policies that operate against a set of claims using our Simple Expression Evaluator project, currently on CodePlex. This technique will show how a simple but powerful and flexible claims-aware rules engine can easily be constructed using any expression evaluator and a set of claims.

Flowing Identity from a Client to a Service when using RESTful WCF Part 1 – The Problem

The digital representation (or identity) of users accessing connected applications will be increasingly modeled using the the concept of Claims. If you’re workingimage with SOAP based web services then the problem of how to implement claims based access control into your WCF services is is a fully solved problem. Whether or not you are using the new Zermatt framework or the claims based identity support in the System.IdentityModel namespace there exists plenty of guidance, available on the web and in books, to help you get everything wired together in a predetermined way. If you’re writing a REST API, however, things aren’t so simple.

SOAP vs REST in WCF – who cares? A service is a service, right?

All of the claims based security support in WCF relies on SOAP envelope headers to transmit a user’s claims from the service consumer to the service. This is to be expected, as several WS-* specs play an important role in WCF’s security support. As a result, if you are using a SOAPless WCF binding such as the RESTful WebHttpBinding, the best you can get for free is transport level security. That means you’re pretty much limited to transmitting authentication credentials, such as a username/password pair (via Http Basic Auth) , a Certificate, etc. If you have a security token containing claims you’d like to pass along, such as a SAML token, it isn’t immediately obvious how to flow that token from the service consumer to the service provider.

Hey, SOAP doesn’t have a patent on Envelopes!

In a RESTful API there is no “envelope” inherent in the message payload itself like there is with SOAP messages.  Indeed, when retrieving data from a RESTful service, there is no message payload at all. The entire scope of a GET request is communicated via the URL. Unlike SOAP, however, the transport protocol you will be using with REST is not a configurable, deploy-time variable. REST operates over HTTP by definition, and the HTTP protocol specifies its own message envelope that supports message headers. These are just the standard, everyday HTTP headers you already know and love. Therefore, we decided the best place for a security token to be stashed when working with RESTful WCF was in a custom HTTP header.

Where do you get a security token from in the first place?

Actually, I’m not going to go into how you go about authenticating a user and obtaining a claim-laden security token (usually a signed, encrypted SAML token). Zermatt should be able to help out with this (see this post for how), and there are also inexpensive .NET libraries you can buy that will abstract away the yucky cryptography/SAML aspects of creating and consuming a proper token. You can even leave these details until the Last Responsible Moment if you want, and, like we are doing, stub out the process of building or obtaining a proper interoperable token and temporarily substitute a simple plain text, character-delimited or XML serialized list of claims to getting everything working and tested and then plug in the gory details later in the process when you’ve selected a vendor/platform/framework as your Security Token Service (STS). For more info on building or buying an STS, see here and here.

The problem distilled

So that leaves us with only a single problem: how do we send a custom HTTP Header containing the logged in users security token with each service request without giving up the convenience of runtime-generated proxies via the WebHttpChannelFactory? Ok, there is another (small) part to the problem: how do we read this custom header on the service side of the wire early enough in the WCF lifecycle so we can unpack the embedded claims and make them available to the service implementation for making authorization decisions?

WCF Extensibility to the rescue!

The specifics of the solution, and code samples, will be presented in the next post.