问题
I have a WebAPI app which I'm using a 3rd party authenticator (Firebase authentication).
I have the authentication working but once the user has logged into my server, I'd like to save credentials and user data into my ASP.NET Identity tables.
I seem to be able to use the UserManager to create accounts if I call this line in my Startup.cs file
services.AddIdentityCore<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
This allows me to add UserManager in my constructor without adding all the login pages and the default cookie authentication scheme I'd normally get if I called AddIdentity()
However, when I add SignInManager in my constructor like this
public ValuesController(SignInManager<ApplicationUser> signInManager)
I still seem to be getting this error.
An unhandled exception has occurred while executing the request. System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Identity.SignInManager`1[mvcWithAuth.Data.ApplicationUser]' while attempting to activate 'testWebAPIFB.Controllers.ValuesController'.
This seems to mean that AddIdentityCore doesn't add SignInManager. How do I add SignInManager as a class to be dependency injected?
回答1:
You should use AddIdentity because the SignInManager is not registered in DI Container
like
services.AddIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
or
Register the SignInManager
services.TryAddScoped<SignInManager<ApplicationUser>>();
回答2:
This seems to mean that AddIdentityCore doesn't add SignInManager.
That's true.If you check the source code of Addidentity and AddIdentityCore, you will find that AddIdentityCore registers the UserManager only without SignInManager
To add SignInManager with AddIdentityCore, you could try:
IdentityBuilder builder = services.AddIdentityCore<ApplicationUser>();
builder = new IdentityBuilder(builder.UserType, builder.Services);
builder.AddEntityFrameworkStores<ApplicationDbContext>();
builder.AddSignInManager<SignInManager<ApplicationUser>>();
Refer to .Net Core 2.0 Web API using JWT - Adding Identity breaks the JWT authentication
回答3:
SignInManager is registered by of AddIdentity. AddIdentityCore only register UserManger.
in you code use,
services.AddIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
Edit: To make JWTBearer as default authentication scheme, Here is what I did,
services.AddDbContext<ApplicationDbContext>(/*options => Db Config*/);
services.AddIdentity<ApplicationUser>(cfg =>
{
cfg.Password.RequireDigit = true;
cfg.Password.RequiredLength = 8;
cfg.Password.RequireNonAlphanumeric = false;
cfg.Password.RequireUppercase = false;
cfg.Password.RequireLowercase = true;
cfg.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(cfg =>
{
cfg.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
cfg.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Issuer"],
IssuerSigningKey = new
SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
};
});
回答4:
Using this code will work for you.
In your controller
private readonly SignInManager<User> _signInManager;
public SomeController(
SignInManager<User> signInManager)
{
_signInManager = signInManager;
}
In your Startup.cs
services
.AddIdentity<User, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
来源:https://stackoverflow.com/questions/57177109/how-do-i-dependency-inject-signinmanager