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.
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>();