JonPSmith / AuthPermissions.AspNetCore

This library provides extra authorization and multi-tenant features to an ASP.NET Core application.
https://www.thereformedprogrammer.net/finally-a-library-that-improves-role-authorization-in-asp-net-core/
MIT License
770 stars 158 forks source link

Changing out IdentityUser #5

Closed cwbrandsdal closed 2 years ago

cwbrandsdal commented 2 years ago

Is there any way to change out the default IdentityUser class with a custom class? When I use IdentityDbContext it crashes because the library expects it to be IdentityDbContext in IndividualAccountsAddSuperUser.


Christopher

JonPSmith commented 2 years ago

Hi @cwbrandsdal,

I did wonder about that! Could you send me the code: specifically

JonPSmith commented 2 years ago

Sorry, could you also send over the exception you get. Thanks.

cwbrandsdal commented 2 years ago

For now my class is just an empty class inheriting from IdentityUser. public class ApplicationUser : IdentityUser { }

Here is my ConfigureServices:

` public void ConfigureServices(IServiceCollection services) {

        services.AddDbContext<AppIdentityDbContext>(options =>
          options.UseSqlServer(
              Configuration.GetConnectionString("IdentityConnection")));
        services.AddDatabaseDeveloperPageExceptionFilter();

        services.AddDefaultIdentity<ApplicationUser>(options =>
                options.SignIn.RequireConfirmedAccount = false)
            .AddEntityFrameworkStores<AppIdentityDbContext>();
        services.AddControllersWithViews()
            .AddRazorRuntimeCompilation();

        //These are methods from the ExamplesCommonCode set up some demo users in the individual accounts database
        //NOTE: they are run in the order that they are registered
        services.AddHostedService<HostedServiceEnsureCreatedDb<AppIdentityDbContext>>(); //and create db on startup
        services.AddHostedService<HostedServiceAddAspNetUsers>(); //reads a comma delimited list of emails from appsettings.json

        services.RegisterAuthPermissions<PermissionsEnum>(options =>
        {
            options.TenantType = TenantTypes.HierarchicalTenant;
            options.AppConnectionString = Configuration.GetConnectionString("IdentityConnection");
        })
            //NOTE: This uses the same database as the individual accounts DB
            .UsingEfCoreSqlServer(Configuration.GetConnectionString("IdentityConnection"))
            .IndividualAccountsAuthentication()
            .RegisterTenantChangeService<DataTenantChangeService>()
            .AddRolesPermissionsIfEmpty(ExampleAuthSetupData.BulkLoadRolesWithPermissions)
            .AddTenantsIfEmpty(ExampleAuthSetupData.BulkHierarchicalTenants)
            .AddAuthUsersIfEmpty(ExampleAuthSetupData.UsersRolesDefinition)
            .RegisterFindUserInfoService<IndividualAccountUserLookup>()
            .RegisterAuthenticationProviderReader<SyncIndividualAccountUsers>()
            .AddSuperUserToIndividualAccounts()
            .SetupAspNetCoreAndDatabase();

        //This registers all the code to handle the shop part of the demo
        //Register RetailDbContext database and some services (included hosted services)
        services.RegisterDataCode(Configuration);
        //Add GenericServices (after registering the RetailDbContext context
        services.GenericServicesSimpleSetup<DataDbContext>(Assembly.GetAssembly(typeof(ListSalesDto)));
    }`

Here is my DBContext:

` public class AppIdentityDbContext : IdentityDbContext { public AppIdentityDbContext(DbContextOptions options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }
}`

Here is the error I get on launch:

An error occurred while starting the application. AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims'.) (Error while validating the service descriptor 'ServiceType: AuthPermissions.SetupCode.IFindUserInfoService Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup'.) (Error while validating the service descriptor 'ServiceType: AuthPermissions.AdminCode.ISyncAuthenticationUsers Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers'.) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)

InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims'. Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor)

InvalidOperationException: Error while validating the service descriptor 'ServiceType: AuthPermissions.SetupCode.IFindUserInfoService Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup'. Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor)

InvalidOperationException: Error while validating the service descriptor 'ServiceType: AuthPermissions.AdminCode.ISyncAuthenticationUsers Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers'. Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor)

AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims'.) (Error while validating the service descriptor 'ServiceType: AuthPermissions.SetupCode.IFindUserInfoService Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup'.) (Error while validating the service descriptor 'ServiceType: AuthPermissions.AdminCode.ISyncAuthenticationUsers Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers'.) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options) Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder) Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter.CreateServiceProvider(object containerBuilder) Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() Microsoft.Extensions.Hosting.HostBuilder.Build() TrackSys.Web.Program.Main(string[] args) in Program.cs + CreateHostBuilder(args).Build().Run();

Show raw exception details InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.AddPermissionsToUserClaims'. Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)

Show raw exception details InvalidOperationException: Error while validating the service descriptor 'ServiceType: AuthPermissions.SetupCode.IFindUserInfoService Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.IndividualAccountUserLookup'. Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)

Show raw exception details InvalidOperationException: Error while validating the service descriptor 'ServiceType: AuthPermissions.AdminCode.ISyncAuthenticationUsers Lifetime: Transient ImplementationType: AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'AuthPermissions.AspNetCore.Services.SyncIndividualAccountUsers'. Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.ValidateService(ServiceDescriptor descriptor) Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)

Show raw exception details .NET 5.0.10 X64 v5.0.0.0 | Microsoft.AspNetCore.Hosting version 5.0.10+b92c9f50f0333ea661785ba849f303cde6a93844 | Microsoft Windows 10.0.19043 | Need help?

JonPSmith commented 2 years ago

Hi @cwbrandsdal,

OK, I have released version 1.4.0 of this library which fixes this issue, but if you want to use a custom IdentityUser you will need to write some code yourself.

First, here are the new extensions that are added in Version 1.4.0 which I had to write as a developer cannot write these.

Second, here is a list of the other parts of the code that you need to write. There are existing versions of these clases / methods, but you need to create new version with UserManager<IdentityUser> changed toUserManager<YourCustomIdentityUser> They are:

The Setup Authentication documentation has been updated to define this.