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?
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:
Microsoft.IdentityModel
package and de-reference the dllSystem.IdentityModel.Services.WSFederationAuthenticationModule
reference from <system.webServer><modules>
in <system.web><httpModules>
<authentication mode="Forms"><forms loginUrl="~/Account/LogOn" /></authentication>
And this got the original WIF3.5 / MVC3 Code Sample working under.NET 4.5