Finally managed to solve a weird issue with external Google authentication in a new MVC 5 application I am working on (CrowdBacklog). This is to help me remember what to do and hopefully help others fix their issues if they stumble upon it…
The Scenario
- VS2013 update 2
- Brand new MVC 5 project targeting .Net 4.5.1 – no old MVC4 / Web Forms crud messing things up
- Startup.Auth.cs has been updated with Google clientid and secret.
- Web.config setting to allow different Google clientid to be used for debug/release
The Symptoms
- Executing locally on Windows 8.1 IIS Express with LocalDb in App_Data works perfectly
- Executing on a third party hosted IIS 7.5 web server with SQL Server 2008 sp3 fails
The failure occurs after having been redirected to Google login and given the application permission. Using fiddler I can see that Google redirects back to /signin-google with a bunch of query parameters as expected. This then redirects to /Account/ExternalLoginCallback then directly on to /Account/Login where the site presents the login form again without having accepted the Google data.
The Solution
After much head scratching, googling and experimenting with different settings the following changes fixed the issue. I actually suspect that it is only the last one that is required but the other ones shouldn’t harm you…
- Set an explicit Machinekey in Web.config – the hosted server is actually a load balanced Web Farm so for AntiForgeryToken validation to work they need to have the same encryption settings.
- Ensure that FormsAuthentication module is removed under <system.webServer> in Web.config
- Update all the NuGet packages to latest version (I had multiple Owin and Identity related updates pending).
- Fix bindingredirects in Web.config to point to the correct versions of the new Assemblies under the <runtime> node
- Switch off Session state in web.config under <systen.web> node
<sessionState mode="Off"/>
The problem with Session state seems to be related to how Owin and the old ASP.Net stuff handle cookies with Owin losing cookies if cookies are removed using old style code. Found the clue on StackOverflow http://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser
Must Have Session State?
[AllowAnonymous] public ActionResult Login(string returnUrl) { //Ensure Session has at least one value Session["EnableExternalAuth"] = true; return View(); }
If you can’t switch off Sessions state then ensuring that the user has at least one value in Session before the login occurs should fix it.
http://stackoverflow.com/questions/22535146/owin-openid-provider-getexternallogininfo-returns-null and http://stackoverflow.com/questions/19453293/asp-net-mvc-5-vs2013-final-facebook-login-with-owin-fails-logininfo-is-null