8

我正在使用 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" }
                );
        });
    }

谢谢你的帮助

4

3 回答 3

7

' 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()不支持此参数,要检查它,您必须使用另一个显式方法

于 2016-04-03T11:04:26.817 回答
1
var user = await userManager.FindByEmailAsync(model.Email);
var result = await signInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, false);
于 2019-08-20T15:01:07.187 回答
0

如果您正在使用为 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

于 2020-12-28T02:12:20.333 回答