Search code examples
c#asp.net-corerazor-pagesasp.net-core-2.2asp.net-core-identity

ASP.NET Core Identity - LoginPartial broken after scaffolding identity


I created a new Project from the VS 2017 template (web application with individual user accounts).

This adds the ASP.NET Core Identity as default UI (using the UI from a nuget).

  services
    .AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

With this nuget everything works as expected. Especially the loginPartial which shows the username once a user has logged in and shows the Login Button right after clicking logout.

Once I scaffold the layout and apply the changes (according to the guide in the docs) the Logout does not remove the name and show the login button anymore (right after the click on logout). The change only happens when I click on a link to another page.

Of course I changed the configuration (according to the guide):

 services
   .AddIdentity<Data.Entities.ApplicationUser, IdentityRole>()
   .AddEntityFrameworkStores<ApplicationDbContext>()
   .AddDefaultTokenProviders();

Does anyone know how to fix this or what the difference is between the DefaultUI and the scaffolded classes?


Solution

  • There's a GitHub issue that describes the exact problem you're running in to. The Razor Class Library (RCL) implementation you were using indirectly before scaffolding has an OnPost implementation in Logout.cshtml.cs that looks like this:

    public override async Task<IActionResult> OnPost(string returnUrl = null)
    {
        await _signInManager.SignOutAsync();
        _logger.LogInformation("User logged out.");
        if (returnUrl != null)
        {
            return LocalRedirect(returnUrl);
        }
        else
        {
            // This needs to be a redirect so that the browser performs a new
            // request and the identity for the user gets updated.
            return RedirectToPage();
        }
    }
    

    As the inline comment explains, it's a RedirectToPage that's needed to ensure the identity gets reloaded after being cleared. If you look at your scaffolded version of this method, you'll find that it has the following in the else branch:

    return Page();
    

    That's the problem. There's no redirect, so there's no reloading of the identity. You can resolve the problem by switching that to use RedirectToPage, as shown in the RCL implementation I called out above.