Monday, July 31, 2006

The Problem

So, let's say you are building a claims-based application for Active Directory Federation Services (ADFS) and you want to use VS.NET 2005 to do this.  Alternately, let's say you are customizing some of the built in pages that come with the federation server or federation server proxy and want to use VS.NET for that.

As things stand today, there is a minor annoying friction point here as the ADFS installer doesn't provide a nice clean way to set a reference to the code you need in System.Web.Security.SingleSignOn and such.  Even if you are developing on a 2003 box (which a lot of serious web devs do, although I still stumble along with XP as its the company standard) and actually install ADFS, you don't see these assemblies in the .NET tab on the add reference UI.  The problem is that the ADFS installer puts the assemblies directly in the GAC and doesn't leave a copy on the "normal" file system (which the compilers actually need), nor does it bother to create a registry key under:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx

(which is the little bit of magic that gets your assembly in the .NET tab).  Multiply this by a large team working on a claims app, and this can be a drag.

The Solution

So, what's a dev to do?  Well, you can definitely copy the assemblies yourself, GAC them and create a registry key and probably do all that with a little batch file if you are so inclined.  Or, you can go over the top and create your own MSI installer package that does this for you.

As a little experiment to see if I could do this quickly and learn how to do some new stuff in MSI that  thought I'd need later on, I did the latter.  It took about an hour over lunch one day.

I'd love to just distribute the msi package directly, but I won't consider doing that unless MS gives me permission to do so (which I don't expect to get).  So, that won't happen.  However, I will tell you how to build your own (fairly) painlessly.  For this, you will need:

Ingredients

  • One copy of Windows Installer XML (WiX) 2.0 (3.0 might work as well, but I didn't bother trying)
  • One copy of the ADFS.msi package that comes with R2 (dig around on the install media for it), or alternately, the 3 assemblies that come with ADFS that are installed the GAC that you hoisted from a normal install
  • One copy of my sample WiX file that will create the MSI (see link at bottom)

Recipe

  1. Place the vsadfs.wxs file in a new clean directory on your file system
  2. Use dark.exe from the WiX distro to reverse engineer ADFS.msi in order to get its files into a handy .cab format, ignoring the error from Dark (<wixpath>\dark -x bin -out adfs.wxs adfs.msi)
  3. Grab the three assembly files (S.Web.Security.SSO *) from the cab file and stick them in a directory called "files" underneath the directory where you put my vsadfs.wxs file
  4. Run these two commands from the command prompt, filling in the path to your WiX binary install where appropriate (unless you have that on your path, obviously):
    1. <wixpath>\candle vsadfs.wxs
    2. <wixpath>\light -out vsadfs.msi vsadfs.wixobj <wixpath>\wixui.wixlib -loc <wixpath>\WixUI_en-us.wxl

You now have a working msi installer that will install (and uninstall and repair!) these things for you.  You may notice that the UI thing I used, WiXUI, shows a license screen and shows the CPL license there.  That's because we didn't supply a license.rtf file in our directory, so WiXUI picked up the one that comes with WiX in its directory.  Feel free to change it.  If you want to eliminate that dialog completely, you are on your own.

Caveats

  • This will NOT give you a working version of an ADFS-enabled web server!  You cannot use this to actually generate a SingleSignOnIdentity object to be used for testing.  You would need some sort of a mock object thingy to do that for you (may that's next?).  All it really does is let set a reference in VS.NET and compile the code, but that's better than what you had before.
  • Additionally, my current installer uses different component GUIDs for the version of the files that go in the GAC.  I'm not sure if it would be the right thing to reuse the component GUIDs from the real ADFS install which puts these components in the GAC or not.  The only time this might be an issue was if you ran this installer on a box that already has ADFS installed.  I'm not sure what would happen, but right now it seems better to keep them separate. 
  • The installer allows specify the install location if you want to change it and breaks the VS.NET and GAC install stuff into separate features so that you don't have to install both if you don't want.  This can be customized via the feature tree dialog.
  • The installer does not bother to check if you have VS.NET 2005 or even .NET 2.0 installed.  This would be a good sanity check for mass market usage, but I'm hoping the users of this are not too insane. 
  • The installer defaults to a "per-machine" install instead of per-user.
  • Repackaging Microsoft's installer is probably a violation of something and may void your warranty or get you in some sort of trouble that I had not fully considered when offering this suggestion.

The Future

I'm hoping that future versions of ADFS will have this scenario already considered so that things like this won't be necessary.  Perhaps we can convince the team to ship this as part of the product or as a free download/sample solution?  I wouldn't be surprised to see these assemblies in a future version of the .NET Framework as well, which would mean that we'd get this for free another way.  Until then...

(Updated 2 Aug 2006 changed to zip file)

vsadfs.zip (1.54 KB)
Monday, July 31, 2006 4:18:01 AM (Central Daylight Time, UTC-05:00)  #    Comments [3]  | 

Theme design by Jelle Druyts