Search code examples
c#asp.netasp.net-mvcasp.net-coreasp.net-identity

How can I implement SignInManager without a database for a development environment?


I am trying enable authorization and authentication on a Web Application using ASP.NET Identity. I am trying to use the SignInManager, but when it calls PasswordSignInAsync it is looking for a database. Is there any way to use it with in-memory data (a collection of users for example) for testing purposes?

I am using the default ApplicationUser class(Model).

public class ApplicationUser : IdentityUser
{

    public Guid UserId { get; set; }
    public string Name { get; set; }
    public string Password { get; set; }
 }

And this is the Login ActionResult method on the controller.

[HttpPost]
public async Task<ActionResult> Login(LoginViewModel viewModel, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var signInResult = await _signInManager.PasswordSignInAsync(viewModel.Email, viewModel.Password,
                                                                   true, false);
        if (signInResult.Succeeded)
            ......
    }
}

The _signInManager.PasswordSignInAsync call looks for a database and I don't see any useful overloads to do anything different.


Solution

  • You can use SignInAsync method instead and create a user object in memory, the following code worked for me to sign in a user that does not exist in database.

    var appUser = new ApplicationUser
    {
        Id = 1,
        UserName = viewModel.UserName,
        Email = viewModel.UserName,
        SecurityStamp = Guid.NewGuid().ToString()
    };
    try
    {
        var userPrincipal = await _signInManager.CreateUserPrincipalAsync(appUser);
        foreach(var claim in userPrincipal.Claims)
        {
            appUser.Claims.Add(new ApplicationUserClaim { UserId = appUser.Id, ClaimType = claim.Type, ClaimValue = claim.Value });
        }
        await _signInManager.SignInAsync(appUser, viewModel.RememberMe);
        return RedirectToLocal(returnUrl);
    }
    catch (Exception ex)
    {
        // Log Exception
        ModelState.AddModelError(string.Empty, "Invalid login");
        return View();
    }
    

    The other option is to customise identity storage providers to use your none persistance storage (e.g. EF7 InMemoryDatabase).

    see the following link for more information

    identity-custom-storage-providers