Search code examples
c#entity-framework-coreasp.net-identity

EF Core 8 Identity - Issue with SignInManager / _loginPartial


In my EF Core 8 web app with Identity, my login partial is not working (anymore).

The Identity pages are not loading, nor seem even the corresponding controller actions to be triggered.

I can therefore not make use of the Identity functionalities.

I have a custom UserManager appUserManager<User> and a custom user class User.

My appuserManager<User> has no further methods at this stage, I just prepared the class, yet.

public class AppUserManager : UserManager<User>
{
    
    private readonly IHttpContextAccessor _httpContextAccessor;
    private readonly AppDbContext _context;

    public AppUserManager(IUserStore<User> store,
                            IOptions<IdentityOptions> optionsAccessor,
                            IPasswordHasher<User> passwordHasher,
                            IEnumerable<IUserValidator<User>> userValidators,
                            IEnumerable<IPasswordValidator<User>> passwordValidators,
                            ILookupNormalizer keyNormalizer,
                            IdentityErrorDescriber errors,
                            IServiceProvider services,
                            ILogger<UserManager<User>> logger,
                            IHttpContextAccessor httpContextAccessor,
                            AppDbContext context)
        : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors,
            services, logger)
    {
        _httpContextAccessor = httpContextAccessor;
        _context = context;
    }

[...]

}

Therefore, i registered the identity service as follows in my program.cs:

builder.Services.AddIdentity<User, Role>(options => options.Sign.RequireConfirmedAccount = true)                
                .AddSignInManager<SignInManager<User>>()
                .AddEntityFrameworkStores<AppDbContext>()
                .AddUserManager<AppUserManager>()
                .AddRoleManager<AppRoleManager>()                
                .AddDefaultTokenProviders();

The login partial is the following:

@using MyApp.Areas.Admin.Users
@using Microsoft.AspNetCore.Identity
@using MyApp.Areas.Admin.Sign


@inject SignInManager<User> SignInManager
@inject AppUserManager AppUserManager

<ul class="navbar-nav">
    @if (SignInManager.IsSigned(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity?.Name!</a>
    </li>
    <li class="nav-item">
        <form  class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>  
}
</ul>

What happens now, is that all the identity pages (login, register, etc...) are not loading, instead i stay on the page i am coming from (so no redirect).

I also noticed the URL called being https://localhost:1234/?area=Identity&page=/Account/Login instead of

https://localhost:1234/Identity/Account/Login.

If i call the Route direcltly, I get an 404 error.

When I rollback the custom appUserManager class and register the default Identity Service in my program.cs instead, I can access the Identity pages and they work as intended by MS.

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.Sign.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<AppDbContext>();

I also tried to create a custom appSignInManager, that uses directly the User class instead of IdentityUser, but it did not solve the issue either.

Furthermore, i tested serveral combinations in the _loginPartial and program.cs of the original SignInManager and my inherited class with User / IdentityUser without success.

I am probably just blind for not finding an obvious issue but still - I have no idea how to get this going.


Solution

  • Nevermind, i found the issue. To solve it, i had to add .AddDefaultUI() in the identity service registration in my program.cs class and register the SignInManagers afterwards:

    builder.Services.AddIdentity<User, Role>(options => options.SignIn.RequireConfirmedAccount = true)
    
                .AddEntityFrameworkStores<AppDbContext>()
                .AddUserManager<AppUserManager>()
                .AddRoleManager<AppRoleManager>()
                .AddDefaultUI()
                .AddDefaultTokenProviders();
    
    
    builder.Services.TryAddScoped<SignInManager<User>, AppSignInManager>();
    builder.Services.TryAddScoped<AppSignInManager, AppSignInManager>();