Authentication and Authorization without Entity Fr

2020-06-08 06:19发布

问题:

I'm trying to configure my authentication and authorization using my existing database and tables, without using Entity Framework (using Dapper).

I've got the Dapper configured correctly, now I'm trying to hook up the SignInManager, and UserManager to call my database via Dapper, but before that can happen, I'm running into some errors with my custom role store.

Here's the error that I'm receiving when I click the "Register" button on the website (this is just a plain project with all of the pre-defined account etc stuff out of the box)

InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNet.Identity.IRoleStore`1[TestAsyncWebsite.Configuration.WrestleStatRole]' while attempting to activate 'Microsoft.AspNet.Identity.RoleManager`1[TestAsyncWebsite.Configuration.WrestleStatRole]'

For now, here's how I have configured my custom user, role, userstore, role store, usermanager, and rolemanager:

    public class WrestleStatUser : ApplicationUser
    {
        public WrestleStatUser() : base()
        {

        }
    }

    public class WrestleStatRole : IdentityRole
    {

    }

public class WrestleStatUserStore : IUserStore<WrestleStatUser>
{
   // all methods implemented
}

public class WrestleStatRoleStore : IRoleStore<WrestleStatRole>
{
   // all methods implemented
}

    public class WrestleStatUserManager : UserManager<WrestleStatUser>
    {
        public WrestleStatUserManager(IUserStore<WrestleStatUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<WrestleStatUser> passwordHasher, IEnumerable<IUserValidator<WrestleStatUser>> userValidators, IEnumerable<IPasswordValidator<WrestleStatUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IEnumerable<IUserTokenProvider<WrestleStatUser>> tokenProviders, ILogger<UserManager<WrestleStatUser>> logger, IHttpContextAccessor contextAccessor)
            : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, tokenProviders, logger, contextAccessor)
        {
        }
    }

public class WrestleStatRoleManager : RoleManager<WrestleStatRole>
{
    public WrestleStatRoleManager(IRoleStore<WrestleStatRole> store, IEnumerable<IRoleValidator<WrestleStatRole>> roleValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, ILogger<RoleManager<WrestleStatRole>> logger, IHttpContextAccessor contextAccessor) : base(store, roleValidators, keyNormalizer, errors, logger, contextAccessor)
    {
    }
}

And here's my startup.cs:

    services.AddIdentity<WrestleStatUser, WrestleStatRole>()
        .AddUserStore<WrestleStatUserStore>()
        .AddUserManager<WrestleStatUserManager>()
        //.AddRoleStore<RoleStore>()
        .AddRoleManager<WrestleStatRoleManager>()
        .AddDefaultTokenProviders();

What am I missing here? The error says something about the RoleManager, I've already defined my custom RoleManager...

回答1:

one problem I see is your WrestleStatRole inherits from IdentityRole which may sound like part of Identity but its really part of EntityFramework Identity implementation, if you are trying to do things without EF you should not inherit from that.

You would need your own role class and should not use any classes from EF implementation.

Similarly the ApplicationUser that you inherit from in WrestleStatUser is in the web app project models folder, but make sure it doesn't inherit from IdentityUser which is part of the EntityFramework implementation of identity

To not use Entity Framework you must implement IUserStore and IRoleStore and register those with di services

services.AddScoped<IUserStore<WrestleStatUser>, UserStore<WrestleStatUser>>();
services.AddScoped<IRoleStore<WrestleStatRole>, RoleStore<WrestleStatRole>>();

and as mentioned your user and role classes should not inherit from EF implementations, in fact they do not need to inherit from anything at all as long as you have implemented those stores and they work.

You can use the built in UserManager if you implement the userstore and rolestore, it is not required to implement that yourself unless you have other reasons for doing so.

If you need example code you can look at my cloudscribe project I have implemented a custom multi tenant identity implementation that does not use entity framework. Actually I'm supporting mutlple data layers that can be plugged in and EF is one of them but it is abtsracted away from identity bits and I'm not using anything from the Microsoft.AspNetCore.Identity.EntityFrameworkCore namespace at all.