Using a Custom SignInManager

2019-07-22 12:23发布

问题:

I setup identity as follows:

services.AddIdentity<IdentityUser, IdentityRole>(
    c =>
    {
        c.Password.RequireDigit = false;
        c.Password.RequiredLength = 8;
        c.Password.RequireLowercase = false;
        c.Password.RequireNonLetterOrDigit = false;
        c.Password.RequireUppercase = false;
    })
    .AddUserManager<CustomUserManager>()
    .AddUserValidator<CustomUserValidator>()
    .AddCustomStores<PrimaryContext>()
    .AddDefaultTokenProviders();

I'd like to use a custom sign-in manager, but there is no AddSignInManager method. I have seen others suggest I add the following line below the fragment above:

services.AddScoped<SignInManager<IdentityUser>, CustomSignInManager>();

However, this causes an internal server error:

InvalidOperationException: Unable to resolve service for type 'MyProject.Identity.CustomSignInManager' while attempting to activate 'MyProject.Controllers.AccountController'.

How can I get my custom sign-in manager working?

回答1:

Turned out to be a misunderstanding on my part. Rather than the following in my controller:

public AccountController(CustomUserManager userManager,
    CustomSignInManager signInManager)
{
    UserManager = userManager;
    SignInManager = signInManager;
}

This more verbose block of code appears to work in combination with the additional line shown in my original question:

public AccountController(CustomUserManager userManager,
    SignInManager<IdentityUser> signInManager)
{
    if(!(signInManager is CustomSignInManager))
    {
        throw new ArgumentException(
            "signInManager must be an instance of CustomSignInManager");
    }

    UserManager = userManager;
    SignInManager = signInManager as CustomSignInManager;
}

This isn't especially nice but it works.



回答2:

As mentioned in the comments you should be using services.AddScoped<SignInManager<IdentityUser>, CustomSignInManager>();

Even if signinmanagers can be changed in controllers it would be considered as an anti-pattern as it will need to be implemented in each possible controller where you will perform a signin.

The reason to use AddScoped is that it will replace the default implementation, which is what most people want to do.