Identity 3 SignInManager.PasswordSignInAsync() 不返回任何结果

Posted

技术标签:

【中文标题】Identity 3 SignInManager.PasswordSignInAsync() 不返回任何结果【英文标题】:Identity 3 SignInManager.PasswordSignInAsync() doesn't return any result 【发布时间】:2016-07-22 21:07:05 【问题描述】:

我正在使用 Identity 3.0 创建 Web 应用程序,但 SignInManager PasswordSignInAsync() 方法存在问题。我像在文档中一样使用它,但它不返回任何东西(应用程序代码就停在那里) 这是我的控制器代码:

 public class AppController : Controller

    private IAccountService _service;
    private readonly SignInManager<User> _signInManager;
    private UserManager<User> _userManager;

    public AppController(IAccountService service, SignInManager<User> signInManager, UserManager<User> userManager)
    
        _service = service;
        _signInManager = signInManager;
        _userManager = userManager;
    

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginViewModel model)
    
        if (ModelState.IsValid)
        
            var user = await _userManager.FindByEmailAsync(model.Email);
            var password = await _userManager.CheckPasswordAsync(user, model.Password);

            var result = await _signInManager.PasswordSignInAsync(
                model.Email,
                model.Password,
                model.RememberMe,
                lockoutOnFailure: false);

            if (result.Succeeded)
            
                return RedirectToAction(nameof(EmployeeController.Contact), "Employee");
            
            if (result.IsLockedOut)
            
                return View("Lockout");
            
            if(result.IsNotAllowed)
            
                return View("Not Allowed");
            
            else
            
                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                return View(model);
            
        
        return View(model);
    

以及startup.cs文件中的配置:

public void ConfigureServices(IServiceCollection services)
    
        services.AddMvc();
        services.AddCaching();
        services.AddSession(options => 
            options.IdleTimeout = TimeSpan.FromMinutes(30);
            options.CookieName = ".MyApplication";
        );

        services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration["Data:DbContextConnection"]));


        services.AddIdentity<User, UserRole>(config => 
            
                config.User.RequireUniqueEmail = true;
                config.Password.RequiredLength = 8;
                config.Cookies.ApplicationCookie.LoginPath = "/App/Login";
                config.SignIn.RequireConfirmedEmail = false;
                config.SignIn.RequireConfirmedPhoneNumber = false;
            )
        .AddEntityFrameworkStores<ApplicationDbContext,string>()
        .AddDefaultTokenProviders();

        services.AddTransient<IAccountService, AccountService>();
    

public void Configure(IApplicationBuilder app)
    
        app.UseStaticFiles();

        app.UseSession();

        app.UseIdentity();
        app.UseMvc(config =>
        
            config.MapRoute(
                name: "Default",
                template: "controller/action/id?",
                defaults: new  controller = "App", action = "Index" 
                );
        );
    

感谢您的帮助

【问题讨论】:

【参考方案1】:

'PasswordSignInAsync()' 方法不能以 'model.Email' 作为第一个参数, 它可以使用用户名检查用户。方法如下:

 public virtual Task<SignInStatus> PasswordSignInAsync(
    string userName,
    string password,
    bool isPersistent,
    bool shouldLockout) 

如果您想检查电子邮件,您可以使用 SignInAsync() 方法,但这是在检查 CheckPasswordAsync() 之后是真的 以下是您可能会做的:

var user = await _userManager.FindByEmailAsync(model.Email);
var password = await _userManager.CheckPasswordAsync(user, model.Password);

if(password)

   var result = await _signInManager.SignInAsync(
                    model.Email,
                    model.Password,
                    model.RememberMe);
     if (result.Succeeded)
     
          return RedirectToAction(nameof(EmployeeController.Contact), "Employee");
     

但是现在您将无法检查 lockoutOnFailure,因为 SignInAsync() 不支持此参数,要检查它,您必须创建另一个显式方法

【讨论】:

【参考方案2】:
var user = await userManager.FindByEmailAsync(model.Email);
var result = await signInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, false);

【讨论】:

您应该始终在代码中添加描述/cmets,以便用户理解。【参考方案3】:

如果你正在使用为 ASP.NET Core 创建最新标识的 Blazor 实现

    var user = await UserManager.FindByEmailAsync(_loginRequest.Email);

    if (user != null && await UserManager.CheckPasswordAsync(user, _loginRequest.Password))
    
        _showInvalidLoginMessage = false;

        var token = await UserManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "SignIn");

        var data = $"user.Id|token";

        var parsedQuery = System.Web.HttpUtility.ParseQueryString(new Uri(NavigationManager.Uri).Query);

        var returnUrl = parsedQuery["returnUrl"];

        if (!string.IsNullOrWhiteSpace(returnUrl))
        
            data += $"|returnUrl";
        

        var protector = DataProtectionProvider.CreateProtector("SignIn");

        var pdata = protector.Protect(data);

        NavigationManager.NavigateTo("/account/signinactual?t=" + pdata, forceLoad: true);
    
    else
    
        _showInvalidLoginMessage = true;
    

(您需要在项目上安装 Microsoft.AspNetCore.DataProtection

信用:https://github.com/christiansparre/BlazorAuthenticationSample/tree/master/src/BlazorAuthenticationSample.Client/Features/Account/Pages

【讨论】:

以上是关于Identity 3 SignInManager.PasswordSignInAsync() 不返回任何结果的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft Identity 2 SignInManager 从不返回 VerificationRequired

如何与 Windows 服务应用程序共享 MVC 5 Identity 2.0 身份验证(尤其是 SignInManager)?

我可以通过使用 cookie 自动重新登录到我的 SignInManager 和 UserManager (Identity) -> Asp.Net-Core Identity (Deploye

SignInManager PasswordSignInAsync 返回 False

Asp.net Core 2.0 Identity.TwoFactorRememberMe 到期

新功能项目授权