Identity 3 SignInManager.PasswordSignInAsync() doesn't return any result

20,481

Solution 1

The 'PasswordSignInAsync()' method cant take 'model.Email' as the first argument, it can check up for the user using his username.Here is the method:

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



if you want to go through checking the email you can use the SignInAsync() method but that is after checking if the CheckPasswordAsync() is true here is what you could possibly make:

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");
     }
}


But now you wont be able to check the lockoutOnFailure since the SignInAsync() dont support this argument,to check it you have to make another explicit method

Solution 2

var user = await userManager.FindByEmailAsync(model.Email);
var result = await signInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, false);

Solution 3

If you're using creating a Blazor Implementation of the latest Identity for ASP.NET Core

    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;
    }

(You will need to install Microsoft.AspNetCore.DataProtection on project

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

Share:
20,481
PaulJ
Author by

PaulJ

Newbie programmer ,who wants to get more skills in developing application .Maybe one day I will create something huge with your help.

Updated on December 28, 2020

Comments

  • PaulJ
    PaulJ over 3 years

    I am creating web application with Identity 3.0 and have problems with SignInManager PasswordSignInAsync() method. I'm using it just like in documentation, but it doesn't return anything ( application code just stop there ) Here`s my controller code:

     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);
        }
    }
    

    And configuration in startup.cs file:

    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" }
                    );
            });
        }
    

    Thanks for any help

  • Michael
    Michael over 4 years
    You should always add a description/comments to your code to make it easy for users to understand.