Wednesday, September 17, 2008

Hiring a Developer for Non-Developers

OK, this won't be definitive guide on the subject for several reasons. First and foremost, it's just going to be a relatively short blog post. Second, I have no experience hiring developers as a non-developer because I am a developer and I was not hiring developers when I wasn't one. Um... yeah, that sentence works. Third, I am not now nor have I ever been a recruiter or HR professional and so I don't know all the other myriad tips and tricks that could be gained having spent a career as one. What I do have is experience as a developer working with recruiters and might be able to give a bit of insight from the development team side of the relationship.

When hiring for a development team, while it is important to know what technologies and methodologies a candidate is familiar with, there is only a little bit more than looking at the alphabet soup on their resume that can be done in that regard. Yes, you must do what you can to make sure the candidate isn't lying. Any help you can give on determining whether or not a candidate really worked with and knows the MAYDEOP framework will help eliminate the individual lying about it before they or their resume gets to the development team. And it will be appreciated. Well, maybe not, but at least the developers won't get frustrated when a dud does get through. Regardless, the development team will still need to drill candidates on all the details that having years of a successful programming career is the only way to really understand.

What is important to remember is that hiring a developer is all about reducing risk. To that end, what I have found more helpful when working with HR or recruiters is to try and explain the indicators that make a good developer, the indicators that signify increased or reduced risk. Do they come from a good school? Do they take an interest in technology outside of work? Do the have interests other than technology (are they well rounded)? What technology publications do they read? What social / technology groups do they participate in? Do they take an active interest in advancing their career? The list can go on for a while and varies from department to department. The idea is that each question has answers that indicate the probability of whether or not a recruit will be more or less successful in a position at a given company.

It is also important to remember that no one answer is necessarily an automatic ding. They may only have gone through "Bob's How to Talk to Computers" training course as far as formal education goes. But if they have five years of experience, have a successful record of completing projects and have every technical certification in the book, it's probably an individual the team should speak to. I'm not saying that an individual that has singlehandedly caused five lawsuits to be leveled against previous employers should be considered regardless of any positive indicators. What I am saying is that in most cases it is the combination of all the answers, the overall package if you will, that needs to be evaluated.

This definitely is not easy to do. It would be nice to think that you could simply scan a resume and match the acronyms up against the job description. Depending on the position though, this is not even a good first step. Some of the best junior developers I have ever been involved with hiring had no experience in the primary technologies used by the teams I was on. Filtering out candidates based on the acronyms in their experience would have eliminated these individuals before the hiring developers ever saw their resumes. True, we wouldn't know we had missed them and thus probably wouldn't be angry about it. But without those successful hires, it would be even more difficult not to get frustrated interviewing dud after dud just because they have "client side programming" listed on their resume.

Monday, September 8, 2008

IT Consultants, Pro Bono?

I found another interesting question on the internet today, "Isn't it about time that IT consultants start doing pro bono work along the lines of lawyers?" I am inferring from the question that the asker doesn't believe that IT professionals perform that much pro bono work which I think is a big misconception that should be fixed. But there are reasons why that misconception exists and I figure I'll take a stab at explaining that is as well.

The definition I found for pro bono is this:
done or donated without charge
By that definition I know of several ways in which many developers contribute work pro bono. Open source is a great example. All types of software from operating systems, to office productivity to educational games as well as countless other types and many versions of each have been created by the software writing public with no expectation of payment. Another excellent example is after school programs where professionals donate their time to educate children in the use of computers and the basics of programming. I myself spend time watching various forums for people that need help and answer questions when I can. Yes, that's where I find these questions. And let's not forget about the friends and family program that every IT professional I know donates a hefty amount of time to every year cleaning viruses and setting up printers and software. Yes, it is a huge misconception to say that IT professionals don't do pro bono work.

Besides, not everyone feels the need to give back to others in the same way. The best software developers I know are intelligent people with diverse interests. The ones that I would accept work free of charge from simply don't want to spend their entire lives, day-in day-out coding. The best developers I know are musicians, writers and athletes in their spare time. They give back to the community in song, fund raising races, informational blogs, writing stories and sometimes just helping out at the local shelter. They may not be contributing by working in their daily trade, but I would never dare say that they lack the drive to help others.
But this misconception must be coming from somewhere. I see this question in various guises from time to time and I think I know what part of the problem is. When I run across this sentiment it is usually coming from the vicinity of an individual that cannot find an IT professional to set up an office network or write a web site or other application for free even if it would be contributing to a worthy cause. The simple reason for this is lack of time. You may be able to find a lawyer to give legal advice and even argue a case or two pro bono. But in general, I know of no profession where a worker can dedicate themselves without pay to a single project, case or individual for the amount of continuous time usually required by such large IT tasks.

Let's take a look at some guidelines. The Washington State Bar Association recommends that lawyers spend 30 hours per year doing pro bono work. Let's just call that a week. There is no software of significant use that can be written in one man week. Software projects and IT tasks of any consequence just take longer to accomplish. Even a simple website takes more time if you want it to be effective. I have seen small, five-page, web sites created in one week and the results are always less than spectacular. Most results are less than mildly pleasing for that matter. In order to build a web site: the message has to created and different ways of breaking down and conveying that message have to be decided on, a user experience that facilitates the message must be generated, colors need to be chosen, images created, content must be written, domain names registered and hosting environments found or built and set up just to name some of the tasks. If this type of job is done in a single week at best you have a web presence. What you never get is an attractive and effective web site.

Even if you can find an individual that wants to spend 160 hours to write your custom web site or rewire your office network, they probably can not take that time off from their day jobs and dedicate themselves to that project. If your company or organization can afford to be without their web site for six months or their office network for one month while an IT professional does the job in their spare time, you might be able to find someone. But most organizations I know would lose more money without those resources in place than the cost of paying someone to get the job done. One of the reasons why large projects can work as open source is that there are very few if any time constraints.

While the length of a significant IT project is fairly large, IT professionals tend to have less time to work on charitable causes because they usually make less money than lawyers. According to some very rough numbers, attorneys make in the range of %30-%50 more than a programmer. The difference can be even bigger in the real world and it probably isn't any less. A simple fact is that people that make more money can afford to spend more time pursuing interests other than making money. Whether or not they do is a question for someone else to answer on some other day.

All of these factors line up in such a way as to create very few possibilities for a real world IT professional to spend time on large projects free of charge. I would hazard a guess that organizations and web sites geared towards matching available professionals with projects in need of free services don't exist because the match success rate would not be that high. And that just makes it even harder to get people and projects together. By contrast, it is much easier for lawyers to find opportunities to do pro bono work as the framework is in place. At the least, most state bar associations have a group or committee to help with just that task.

There are probably many more facets to the issue that I am missing, but the short of it is that IT professionals do give back. Most just can't do it in large enough lump sums to accomplish the same tasks they generally get paid for. Time constraints, money constraints, life and sanity just prevent IT workers from being able to give large projects away for free on someone else's schedule.

Sunday, September 7, 2008

Google Growing Pains

I ran into something I got a bit of a chuckle out of this morning.  Not a malicious chuckle mind you.  Just an "oops, that's kind of ironic", lighten-up-the-day, smile-to-my-lips sort of thing.
I have an odd sense of humor at the best of times, so just in case you don't get it here is why I found this mildly amusing.  This is a screen shot of Google's virtual reality program directing users to browsers other than Google's own browser, Chrome.

I realize there's a whole bunch of reasons for this that I could only wish were the case for my little company.  Google has many successful as well as yet-to-be-proven products.  Many people in many countries use those products driving Google's remarkable profits.  Despite those facts, this is a sign that there are some far flung departments at Google that just aren't keeping in touch.  This isn't a problem unique to Google by any means. It's just a reminder that anytime a company get's to be of a certain size, roll out timings, acquiring third parties, communication difficulties and any of a plethora of other complications can cause chinks to show in what seems to be an otherwise unified corporate strategy.

On an almost completely random topic, some movie quotes:
El Guapo: Jefe, what is a plethora?
Jefe: Why, El Guapo?
El Guapo: Well, you told me I have a plethora. And I just would like to know if you know what a plethora is. I would not like to think that a person would tell someone he has a plethora, and then find out that that person has *no idea* what it means to have a plethora. 

Tuesday, September 2, 2008

Silverlight, WCF and Authentication

Here is what I wanted to do. I wanted my WCF services to be completely disconnected from my Silverlight web application. I wanted third parties to be able to generate proxies without authenticating and use the web services without authenticating against a web site first. I didn't want to rely on impersonation because the user accounts will be created from within the services and new accounts would then need to be registered with SQL Server security. Ick. I just wanted basic WCF services with message level authentication and a web site hosting a Silverlight application built on top of the services. Should be easy, correct?

Well, as anyone who has tried knows, easy isn't the case. However, I was able to get all this working with the help of quite a few articles. And you can bet accomplishing my goal required hacks, custom code and overcoming several mind bending what-the-f***s along the way. Here I document the journey at a high level with links to details if you're interested. Forgive me if the steps aren't in quite the right order or some details are missing; it's taken me a few weeks to tack together all the bits and pieces.

Membership Authentication
I'm not talking about hiding your services behind a web site and piggy-backing authentication on top of the WCF - ASP.NET compatibility features. I'm talking about true, per-operation message level authentication using a membership provider. This is particularly useful because we are able to use the same provider for the services and web site and yet keep them completely separate. Here's the why-hows. What this ends up forcing you to do is set up a BasicHttpBinding with TransportWithMessageCredential security. That will require you to run all of your services over HTTPS. I use IIS 7 which makes it very easy to create your own SSL certificates for development. There are problems though. Problem One - even though we are using TransportWithMessageCredential security on a basicHttpBinding, Silverlight does not yet support it. Problem Two - cross domain policy files do not yet support the HTTPS protocol. Problem Three - because the services are not relying on impersonation, it is a bit difficult to get the identity of the authenticated user. Problem two is easy to solve so I am going to talk about it first.

HTTPS and Cross Domain Policies.
[EDIT: This is no longer an issue in the release of Silverlight 2. Supposedly, clientaccesspolicy.xml now allows cross domain calls between HTTP and HTTPS. Regardless, I still set up my development environment this way for the small debugging advantage.]
Cross domain policy files are what let you call WCF services from Silverlight applications that are downloaded from different domains. The short version of how to deal with this is that you don't. Cross domain policy files simply don't support HTTPS right now. That's OK though. What I have done is to create a virtual directory in IIS under the web site that hosts my Silverlight application that maps to my services. I also made sure that the pages that host my Silverlight application are also protected by SSL. That way, my Silverlight is downloaded from https://www.example.com/ and my services are at https://www.example.com/services. This satisfies the same domain requirement. At first, this might seem like a performance hit, but since the web pages hosting my Silverlight application are infrequently used (once per login in our case), it's not really that bad at all. While this essentially means that the web site and services do need to exist together for now, once support for HTTPS is introduced in the cross domain policy files, all you need to do is create the file, drop it into the services directory and you can move the virtual directory where ever you want. There are a few other details like making sure you allow anonymous access to the services directory. Authentication will be taken care of by the membership provider when the services are run, but you want people to be able to hit your MEX and WSDL files. You also need to make sure to turn off forms authentication for the services directory or your requests will be run through the ASP.NET authentication process. Since no cookies will be sent with your service calls, requests will fail if you don't disable forms authentication for your services. One upshot of hosting your services and web application in IIS is that you can associate both with the same application pool. If you do so, they will use the same worker process. Since the debugger automatically attaches to the web site worker process, you can debug your services without attaching to the services host by hand. Now on to the harder problem, Problem One.



TransportWithMessageCredential Silverlight Compatibility
It doesn't exist in Silverlight 2 Beta 2. You can make your own though. This post describes how to add your own headers to a WCF call in a Silverlight application. There are a few changes that I needed to make. Most code that uses HTTP needs to be changed to HTTPS. For instance, when adding binding elements to the custom binding you need to change the HttpTransportBindingElement to an HttpsTransportBindingElement. You also need to make sure that you set the security mode for the binding to Transport. The proxy generator will dutifully create your client configuration with the TransportWithMessageCredential. It doesn't hurt to leave them in the configuration, just make sure the default configuration is never used; the runtime will error when it tries to parse the security mode because TransportWithMessageCredential does not exist in the security enumeration in the Silverlight runtime. Getting around it is accomplished by providing your own binding and endpoint address as the per the example in the referenced post. The hardest part was writing the security header so that it was compatible with the WCF security headers. To figure this out, I created a small windows application, hooked it up to the services and inspected the messages server side. I'll paste my security header class below since that code is not included in any of the posts I saw. The frustrating thing about all of this work is that it will all be thrown out when security credentials and TransportWithMessageCredential security are support in Silverlight WCF proxies. Ah well.

Who are you?
Problem number three is getting the identity of the user. I could not find the identity in any of the normal places: OperationContext, HttpContext, Thread.CurrentPrincipal. Nothing. My understanding is that this is because I am not using impersonation, nor do I want to, but if someone knows how to configure things a different way, I'm all ears. My solution was to add a message inspector. Implementing IDispatchMessageInspector allows you to inspect the contents of a message after the credentials in the message have been authenticated. With a little XPath, the authenticated username falls right into your hands, er code... whatever. The point is that you now know the user's identity and can provide it to your routines for authorization purposes. One little gotcha about writing message inspectors is that message can only be read or copied once. Here's an article that explains how to get around it and a conversation on why it works the way it does. Yes, it's an old 'Indigo' article, but it is still relevant.
[EDIT] So I was rereading this article recently because apparently a bunch of people have found it. One change that I made sometime since Silverlight 2 released is that I found out where WCF stuffs identity information. OperationContext.Current.ServiceSecurityContext.PrimaryIdentity. That's it. The message inspectors are no longer necessary if they ever were. I don't know if that's a Silverlight 2 thing or not, but you should all be using the final release now anyway.[/EDIT]


Summary
That's more or less it. Again, I'm sorry for the lack of detail, but others have already done most of the documenting, I just had to put it all together. If you have questions, you can email me. My contact information should be on the side of the blog there somewhere. Silverlight RTM or RTW or CTP or whatever comes next is due out fairly soon from my understanding. At that time I don't think all that code required to solve problem two will be needed any more. But if you need to get this working now like we did, it is possible. And it's not that much work once you understand how all the pieces parts fit together.



The code I promised
Somewhere up above I said that I would provide a little bit of code to demonstrate how to write WCF compatible security headers from a class inheriting from MessageHeader. The credentials object is one of my own devising that keeps the password encrypted in memory and I store it at the top level in my Silverlight Application object, app.xaml. But is should be obvious what information goes where. Oh, except for the username token. In other WCF applications, this is the string "uuid-" followed by a random Guid selected for that instance of the application followed by "-1". e.g. "uuid-12345678-1234-1234-1234-123456789012-1". Here's the code:



public class SecurityHeader : MessageHeader
{

protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion)
{
var timestamp = DateTime.Now;
var application = Application.Current as App;
var credentials = application.Credentials;

var secUtilNamespace =
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
var secExtNamespace =
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

writer.WriteStartElement(
"Timestamp", secUtilNamespace);
writer.WriteAttributeString(
"Id", secUtilNamespace, "_0");
writer.WriteElementString(
"Created", secUtilNamespace, timestamp.ToString("O"));
writer.WriteElementString(
"Expires", secUtilNamespace, timestamp.AddMinutes(5).ToString("O"));
writer.WriteEndElement();
writer.WriteStartElement(
"UsernameToken", secExtNamespace);
writer.WriteAttributeString(
"Id", secUtilNamespace, credentials.UsernameToken);
writer.WriteElementString(
"Username", secExtNamespace, credentials.Username);
writer.WriteStartElement(
"Password", secExtNamespace);
writer.WriteAttributeString(
"Type", secExtNamespace, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
writer.WriteString(credentials.Password);
writer.WriteEndElement();
writer.WriteEndElement();
}

public override string Name
{
get { return "Security"; }
}

public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}

public override bool MustUnderstand
{
get{ return true; }
}
}