2

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?

Diskdrive
  • 18,107
  • 27
  • 101
  • 167

4 Answers4

6

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

Ryan
  • 19,118
  • 10
  • 37
  • 53
1

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

        });
Code Name Jack
  • 2,856
  • 24
  • 40
  • so the only problem is AddIdentity overrides the default authentication scheme to cookie authentication and I'm using JWT tokens to authenticate. So then I just get an authentication error and then re-directs me to the Account/Login page. – Diskdrive Jul 24 '19 at 13:30
  • For that you can set the default authentication scheme to JWT – Code Name Jack Jul 25 '19 at 05:36
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>>();
Nemi Chand
  • 138
  • 1
  • 10
1

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();
Tony Ngo
  • 19,166
  • 4
  • 38
  • 60