Why would FederatedAuthentication.WSFederationAuthenticationModule be null in MVC Azure ACS Federated Authentication?

Jude Fisher picture Jude Fisher · Oct 17, 2012 · Viewed 9.2k times · Source

I'm trying to put together FederatedAuthentication with .NET 4.5, MVC 4, and active redirect using a custom server-side login page, using code from this tutorial, and from this code sample.

Redirecting to the LogOn method of my AccountController works fine, and the method looks like this:

public ActionResult LogOn()
{
    HrdClient hrdClient = new HrdClient();
    WSFederationAuthenticationModule fam = FederatedAuthentication.WSFederationAuthenticationModule; /*** Fails here because this is null **/
    HrdRequest request = new HrdRequest(fam.Issuer, fam.Realm, context: Request.QueryString["ReturnUrl"]);
    IEnumerable<HrdIdentityProvider> hrdIdentityProviders = hrdClient.GetHrdResponse(request);
    ViewData["Providers"] = hrdIdentityProviders;
    return View();
}

This fails because FederatedAuthentication.WSFederationAuthenticationModule is null.

Using VS 2012, I've run the new Identity and Access wizard (which seems to replace the old STS dialog). This has given me a folder of FederationMetadata, which appears correct, and several modifications to my Web.Config. In particular, the modules section looks like this:

<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
  <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
  <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
</modules>

And having seen SO answers 8937123 and 8926099, I've added the following as well:

 <httpModules>
  <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>

And finally my nuget packages config shows Microsoft.IdentityModel, which is correctly referenced by the MVC app:

<packages>
  <package id="Microsoft.IdentityModel" version="6.1.7600.16394" targetFramework="net45" />
</packages>

I've also seen this question on social.msdn, which just seems to suggest that the STS dialog does need to be run.

Can anybody explain why FederatedAuthentication.WSFederationAuthenticationModule would be null, and what I can do to stop this happening?

Answer

Jude Fisher picture Jude Fisher · Oct 18, 2012

I managed to fix this myself, and since there are a few unanswered questions similar to this on SO, I'll leave the question up and post my own answer.

The issue is to do with upgrading the MVC application to .NET 4.5. Much of the WIF functionality remains the same (at least on the surface), but the classes have all moved to different assemblies. I fixed my problem following the migration guidelines here: http://msdn.microsoft.com/en-us/library/jj157089.aspx

The most important thing is to remove old references to the Microsoft.IdentityModel package (v 3.5.0) and make sure they are replaced by similar references to the System.IdentityModel and System.IdentityModel.Services dlls, which should be version 4.0, and come from the GAC rather than an external package.

My steps to fix were:

  • Clean out all the junk I'd added to Web.Config and start again with a default MVC Config file.
  • Remove the Microsoft.IdentityModel package and de-reference the dll
  • Run the Access and Identity wizard in VS 2012
  • Duplicate the System.IdentityModel.Services.WSFederationAuthenticationModule reference from <system.webServer><modules> in <system.web><httpModules>
  • Add <authentication mode="Forms"><forms loginUrl="~/Account/LogOn" /></authentication>
  • Compile, test, dance little jig of delight...

And this got the original WIF3.5 / MVC3 Code Sample working under.NET 4.5