Otrzymuję ten błąd w kontrolerze logowania.
InvalidOperationException: nie można rozpoznać usługi typu „Microsoft.AspNetCore.Identity.UserManager” 1 [Automobile.Models.Account] ”podczas próby aktywacji„ Automobile.Server.Controllers.AuthController ”.
oto konstruktor Auth Controller:
private SignInManager<Automobile.Models.Account> _signManager;
private UserManager<Automobile.Models.Account> _userManager;
public AuthController(UserManager<Models.Account> userManager,
SignInManager<Automobile.Models.Account> signManager)
{
this._userManager = userManager;
this._signManager = signManager;
}
a oto ConfigureServices w startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.Configure<AppConfig>(Configuration.GetSection("AppSettings"));
//var provider = HttpContext.ApplicationServices;
//var someService = provider.GetService(typeof(ISomeService));
services.AddDbContext<Providers.Database.EFProvider.DataContext>(options => options
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly("Automobile.Server")
));
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
options.User.RequireUniqueEmail = false;
})
.AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
.AddDefaultTokenProviders();
//services.AddScoped<SignInManager<Automobile.Models.Account>, SignInManager<Automobile.Models.Account>>();
//services.AddScoped<UserManager<Automobile.Models.Account>, UserManager<Automobile.Models.Account>>();
services.AddMvc();
App.Service = services.BuildServiceProvider();
// Adds a default in-memory implementation of IDistributedCache.
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.CookieHttpOnly = true;
});
}
IdentityUser
jako podstawowa klasa użytkownika, ale potem używaszAutomobile.Models.Account
, która oczywiście nie jest nigdzie zarejestrowana przez ASP.NET IdentityOdpowiedzi:
Musisz użyć tego samego modelu danych użytkownika w SignInManager, UserManager i usługach.AddIdentity. Ten sam podmiot zabezpieczeń jest prawdziwy, jeśli używasz własnej niestandardowej klasy modelu roli aplikacji.
Więc zmień
services.AddIdentity<IdentityUser, IdentityRole>(options => { options.User.RequireUniqueEmail = false; }) .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>() .AddDefaultTokenProviders();
do
services.AddIdentity<Automobile.Models.Account, IdentityRole>(options => { options.User.RequireUniqueEmail = false; }) .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>() .AddDefaultTokenProviders();
źródło
Żeby mieć jasność co do odpowiedzi:
Jeśli używasz klasy
ApplicationUser
w startup.cs:services.AddIdentity<ApplicationUser, IdentityRole>()
wtedy musisz użyć tej samej klasy w swoim kontrolerze podczas wstrzykiwania:
public AccountController(UserManager<ApplicationUser> userManager)
Jeśli używasz innej klasy, takiej jak:
public AccountController(UserManager<IdentityUser> userManager)
wtedy pojawi się ten błąd:
bo użyłeś
ApplicationUser
przy starcie, nieIdentityUser
więc ten typ nie jest zarejestrowany w systemie wtrysku.źródło
Jest to trochę niezwiązane z oryginalnym postem, ale ponieważ Google przenosi Cię tutaj ... jeśli otrzymujesz ten błąd i używasz:
Następnie musisz ręcznie zarejestrować rzeczy, które to
AddIdentity
robią, które można znaleźć tutaj: https://github.com/aspnet/Identity/blob/feedcb5c53444f716ef5121d3add56e11c7b71e5/src/Identity/IdentityServiceCollectionExtensions.cs#L79services.AddHttpContextAccessor(); // Identity services services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>(); services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>(); services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>(); services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>(); services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>(); // No interface for the error describer so we can add errors without rev'ing the interface services.TryAddScoped<IdentityErrorDescriber>(); services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>(); services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>(); services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>(); services.TryAddScoped<UserManager<TUser>>(); services.TryAddScoped<SignInManager<TUser>>(); services.TryAddScoped<RoleManager<TRole>>();
Trzeba wymienić
TUser
iTRole
ze swoimi implementacji tych, lub domyślnieIdentityUser
,IdentityRole
źródło
AddIdentity
iAddJwtBearer
polegała na ustawieniu wszystkich trzech opcji pokazanych w przykładzie; używałem tylkoDefaultAuthenticationScheme
. Nadal otrzymuję plik cookie z powrotem przy logowaniu, ale[Authorize]
teraz działa dla tokenów JWT bez określania AuthenticationSchema.TryAddScoped<UserManager<TUser>>();
iservices.TryAddScoped<SignInManager<TUser>>();
do mojego Startup.cs rozwiązało mój problem.nie zapomnij dodać menedżera ról w ConfigureServices
services.AddDefaultIdentity<IdentityUser>() .AddRoles<IdentityRole>() // <-------- .AddDefaultUI(UIFramework.Bootstrap4) .AddEntityFrameworkStores<ApplicationDbContext>();
źródło
Możesz ustawić IdentityUser i IdentityRole w ConfigureServices wewnątrz klasy Startup indywidualnie, jak pokazano poniżej:
LUB
możesz skonfigurować bezpośrednio w AddIdentity:
źródło
Jeśli używasz „IdentityServer”, to IdentityServer uwierzytelnia użytkownika i autoryzuje klienta. Domyślnie IdentityServer nie dotyczy zarządzania użytkownikami. Ale istnieje wsparcie dla tożsamości asp.net
Więc musisz dodać:
źródło
Musisz zaktualizować swoją klasę Statup.cs poniżej
services.AddIdentity <ApplicationUser, IdentityRole> () .AddEntityFrameworkStores ();
Tutaj: ApplicationUser to moja niestandardowa klasa modelu.
źródło