Home » c# » c# – OWIN authentication succeeds but User.Identity.IsAuthenticated is false

c# – OWIN authentication succeeds but User.Identity.IsAuthenticated is false

Posted by: admin February 21, 2020 Leave a comment

Questions:

I developed a site that uses OWIN authentication. All worked well, but suddenly, without any code change, site authentication stopped working. When I enter username and password, the call to SignInManager.PasswordSignInAsync succeeds but User.Identity.IsAuthenticated remains false.

This is the Startup.Auth.cs:

public partial class Startup
{
    // For more information on configuring authentication, please visit https://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
        app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

        // Enables the application to remember the second login verification factor such as phone or email.
        // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
        // This is similar to the RememberMe option when you log in.
        app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");

        //app.UseTwitterAuthentication(
        //   consumerKey: "",
        //   consumerSecret: "");

        //app.UseFacebookAuthentication(
        //   appId: "",
        //   appSecret: "");

        //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
        //{
        //    ClientId = "",
        //    ClientSecret = ""
        //});
    }
}

Here is where authentication is performed:

    public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
    {
        var result = base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout).Result;
        if (result == SignInStatus.Success)
        {
            ApplicationUser user = this.UserManager.FindAsync(userName, password).Result;
            user.LastLoggedOn = DateTime.Now;
            if (!user.FirstLoggedOn.HasValue)
                user.FirstLoggedOn = user.LastLoggedOn;
            this.UserManager.UpdateAsync(user);
        }
        return Task.FromResult(result);
    }

One thing to note. I use this exact same code in other sites and in all authentication is working. Only one site has this problem.

This is the Login method of Accountcontroller:

    //
    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<JsonResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            var mensaje = GetModelErrorMessages();
            return Json(mensaje, JsonRequestBehavior.AllowGet);
        }

        if (String.IsNullOrEmpty(returnUrl))
            returnUrl = "/";

        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, change to shouldLockout: true
        var result = await SignInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                return Json(returnUrl, JsonRequestBehavior.AllowGet);
            case SignInStatus.LockedOut:
                return Json("ERROR: El usuario está bloqueado.", JsonRequestBehavior.AllowGet);
            case SignInStatus.RequiresVerification:
                return Json(Url.Action("SendCode", new { ReturnUrl = returnUrl, model.RememberMe }));
            case SignInStatus.Failure:
            default:
                var mensaje = "ERROR: Nombre de usuario o contraseña incorrectos.";
                return Json(mensaje, JsonRequestBehavior.AllowGet);
        }
    }

As you see, this returns JSON. That JSON contains the return url that is used to redirect to other site, as this script shows:

function performLogin(loginUrl)
{
    runWaitMe('#loginform', "Ingresando...");
    $.ajax({
        type: 'POST',
        url: loginUrl,
        data: $('#frmLogin').serialize()
    }).done(function (data) {
        if (displayError(data))
            hideWaitMe('#loginform');
        else
            location.href = data;
     }).fail(function (jqXHR) {
            hideWaitMe('#loginform');
            showError(jqXHR);
    });
}

I repeat, this same code is in all sites I develop and it works for all of them.

Maybe for this case, the cookie cannot be saved.

What can I check?

Regards
Jaime

How to&Answers: