我正在开发 ASP.NET Core 7 MVC Web 应用程序。我正在使用实体框架代码优先。我所有的代码似乎都有效。我可以添加迁移、更新数据库并运行我的 Web 应用程序。
登录后,我的自定义
SignInManager
被调用并返回成功的 SignInResult
。然而,在任何视图中,当我使用 @if (SignInManager.IsSignedIn(User))
时,这总是错误的。
这是我的一些代码:
定制
SignInManager
:
public class LookupSigninManager : SignInManager<IdentityUser>
{
private readonly IUserRepository _userRepository;
private readonly ActiveDirectoryService _activeDirectoryService = new();
public LookupSigninManager(
UserManager<IdentityUser> userManager,
IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<IdentityUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<IdentityUser>> logger,
IAuthenticationSchemeProvider schemes,
IUserConfirmation<IdentityUser> confirmation,
IUserRepository userRepository)
: base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation)
{
_userRepository = userRepository;
}
public override async Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
{
var dto = await _userRepository.Get(userName);
if (dto == null)
return SignInResult.Failed;
var user = _activeDirectoryService.GetUser(userName, password);
var result = user != null ? SignInResult.Success : SignInResult.Failed;
return await Task.FromResult(result);
// This always succeeds and returns a SignInResult.Success
}
}
Login.cshtml.cs
:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
// . . . . this uses my LookupSigninManager and always succeeds
}
}
program.cs
- 我怀疑问题出在这里:
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DataContextConnection");
builder.Services.AddDbContext<DataContext>(options =>
{
options.UseSqlServer(connectionString, b => b.MigrationsAssembly("KS.TestLookup.Web"));
});
builder.Services.AddIdentity<IdentityUser, IdentityRole>(o =>
{
o.Stores.MaxLengthForKeys = 128;
o.SignIn.RequireConfirmedAccount = true;
o.Password.RequireDigit = false;
o.Password.RequireLowercase = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.RequireUppercase = false;
o.Password.RequiredLength = 6;
})
.AddSignInManager<LookupSigninManager>()
.AddEntityFrameworkStores<DataContext>()
.AddDefaultTokenProviders();
builder.Services.ConfigureApplicationCookie(o =>
{
o.LoginPath = "/Identity/Account/Login";
});
// Settings
var sm = new SettingsService();
var settings = sm.LoadSettings<AppSettings>();
builder.Services.AddSingleton<AppSettings>(_ => settings);
// Logging
var logger = new AppLogger(new AppLoggerConfig
{
LogFilePath = settings.LogFilePath,
ShowLogLevel = true,
});
builder.Services.AddSingleton<IAppLogger>(_ => logger);
builder.Services.AddScoped<ILayerRepository, LayerRepository>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped(_ => ProductionMapper.Create());
builder.Services.AddControllersWithViews(); //options => options.Filters.Add<ErrorFilter>());
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();
我花了一天的时间在
program.cs
中搜索并尝试了很多建议的 DI 风格,但没有任何效果对我有用。
如果有人能指出我正确的方向,我将非常感激。
更改您的
PasswordSignInAsync
方法,如下所示,您就可以解决问题。
public override async Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
{
var dto = await _userRepository.Get(userName);
if (dto == null)
return SignInResult.Failed;
var user = _activeDirectoryService.GetUser(userName, password);
if (user != null)
{
return await base.PasswordSignInAsync(user, password, isPersistent, lockoutOnFailure);
}
else
{
return SignInResult.Failed;
}
}