Upgrading to ASP.NET 4.5/MVC 4 forms authentication fails

22,668

Solution 1

The issue here is that the default mvc4 internet template is using SimpleMembership to manage membership/roles information. The code in the template has assumption of this and can only work with simplemembership. When you install universal providers the account controller code blows up since it cannot understand universal providers. Look at this post which explains further on this scenario http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx

Solution 2

If your forms authentication ticket needs to be shared between applications using an older version of the .NET framework, you must explicitly configure your .NET 4.5 apps to use the earlier machine compatibility modes, or they will not be able to encrypt/decrypt the forms authentication ticket.

In your .net 4.5 application's web.config, set the compatibility mode attribute:

<system.web>
 <machineKey compatibilityMode="Framework20SP2" /> 
</system.web>

This will allow your .NET 4.5 apps to work with forms authentication tickets generated by earlier .NET versions.

Note: If any of your servers do not have .NET Framework 2.0 SP2 installed, you will need to set the compatibility mode to "Framework20SP1" instead.

MSDN - MachineKeySection.CompatibilityMode Property

Solution 3

For me, I had an issue because there are some changes to the web.config settings you need (from http://www.asp.net/whitepapers/mvc4-release-notes)

<appSettings>
  <add key="webpages:Version" value="2.0.0.0" />
  <add key="PreserveLoginUrl" value="true" />
</appSettings>

Fixing these settings (which it doesn't look like you've added) got things working for me when I had login issues.

Share:
22,668
Dennis Ward
Author by

Dennis Ward

Updated on January 10, 2020

Comments

  • Dennis Ward
    Dennis Ward over 4 years

    I've just downoaded a VS 2012 along with ASP.NET 4.5 and MVC 4.0 and was kicking the tires with a sample app and found that the forms authentication that works perfectly with ASP.NET 4.0/MVC 3 no longer seems to work with the latest release.

    When I make a call to the Login function in the action controller, the WebSecurity.Login call fails:

    public ActionResult Login(LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
        {
            return RedirectToLocal(returnUrl);
        }
    
        // If we got this far, something failed, redisplay form
        ModelState.AddModelError("", "The user name or password provided is incorrect.");
        return View(model);
    }
    

    I've replaced this code with the equivalent in my VS 2010 source, and that also fails (using the now deprecated FormsAuthentication.Authenticate function).

    My question is: Has anybody ported a MVC3 to MVC4 app and found a workaround to this issue? I'm using IIS Express, so I guess that may be causing some problem somehow, but if you have any ideas, I'd appreciate it.

    I copied my configuration from my working asp.net 4/MVC3 app as follows, but no luck (here's the relevant parts):

      <connectionStrings>
        <add name="DefaultConnection" connectionString="Data Source=tcp:sql2k1201.dbprovider.net;Initial Catalog=SQL2012_db;User ID=SQL2012_db_user;Password=dbpassword;" providerName="System.Data.SqlClient" />
      </connectionStrings>
    
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
    
        <authentication mode="Forms">
          <forms loginUrl="~/Account/Login" timeout="2880"/>
        </authentication>
    
        <membership>
          <providers>
            <clear/>
            <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="DefaultConnection"
               enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
               maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
               applicationName="/" />
          </providers>
        </membership>
    
        <profile>
          <providers>
            <clear/>
            <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="DefaultConnection" applicationName="/" />
          </providers>
        </profile>
    
        <roleManager enabled="true">
          <providers>
            <clear/>
            <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnection" applicationName="/" />
          </providers>
        </roleManager>
    
  • Dennis Ward
    Dennis Ward over 11 years
    The web.config I included was only a snippet that had the changes I added for forms authentication. The key/values you have above are in the default web.config, and I didn't remove them (there in my full web.config). Thanks for responding, though.
  • Dennis Ward
    Dennis Ward over 11 years
    James - I tried your suggestion just now and it doesn't seem to make any difference, and I can't log in. Do you think it has anything to do with IIS Express?
  • Dennis Ward
    Dennis Ward over 11 years
    I was just looking over the call to 'WebSecurity.InitializeDatabaseConnection("DefaultConnection‌​", "UserProfile", "UserId", "UserName", autoCreateTables: false);' and looked at the "UserProfile" table in my DB and it was empty. Did they change the schema? When I go to the "ASP.net web site configuration" tool, it shows my users, but the app still will not allow me to login.
  • James H
    James H over 11 years
    This setting applies for both IIS and IIS Express. Since you're sharing the forms auth ticket, you could try the following settings as well <add key="enableSimpleMembership" value="false" /> and <add key="autoFormsAuthentication" value="false" /> under <appSettings>.
  • Dennis Ward
    Dennis Ward over 11 years
    Pranav - thanks for pointing out that article. I noticed that loads of comments about the article mentioned that the new providers were anything but simple, and there is no smooth migration path if you want to convert existing membership/roles to the new schema. It seems to me while they may have tried to simplify a complex system, they have made it more so, and just trying out the new stuff by making a quick change to the web.config results in new tables that don't work with the prior setup. I have more to learn about this for sure!
  • Paul Speranza
    Paul Speranza over 11 years
    James, thank you so much - you have solved my problem in this question stackoverflow.com/questions/11532743/…
  • BigJump
    BigJump over 10 years
    Thanks - we were integrating two .NET 4.5 applications on the same server, but kept on getting "Forms authentication failed for the request. Reason: The ticket supplied was invalid.". Seems something in one of the applications is causing it to be treated like a non 4.5 app.
  • RonnBlack
    RonnBlack almost 10 years
    Thanks... PreserveLoginUrl was the key for my problem. Login was working fine but when using [Authorize(Roles="admin")] it was failing.
  • Baxter
    Baxter about 9 years
    @JamesH I have been looking all over for this solution. I am using a webforms asp.net 4.0 login and my new MVC applications had the httpRuntime target framework set to 4.5.1 by default. Added compatibilityMode to the machineKey fix it. Thank you so much! +1