ASP.NET Core 7 MVC:自定义 SignInmanager IsSignedIn 始终为 false

问题描述 投票:0回答:1

我正在开发 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 风格,但没有任何效果对我有用。

如果有人能指出我正确的方向,我将非常感激。

asp.net-core-mvc identity .net-7.0
1个回答
0
投票

更改您的

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.