Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC框架中使用Identity Core的标识_C#_Asp.net Mvc_Asp.net Core_Asp.net Identity_.net Standard - Fatal编程技术网

C# ASP.NET MVC框架中使用Identity Core的标识

C# ASP.NET MVC框架中使用Identity Core的标识,c#,asp.net-mvc,asp.net-core,asp.net-identity,.net-standard,C#,Asp.net Mvc,Asp.net Core,Asp.net Identity,.net Standard,我在部分切换到.NET标准时遇到问题 我正在将类库迁移到.NET标准的过程中,在这个库中我有存储库和数据库通信。我已经成功地将其迁移到使用AspNetCore.Identity.EntityFrameworkCore。我试图实现的是最终有1个.NET标准项目负责数据库,其中1个MVC.NET Framework、1个API.NET Framework和1个新的.NET核心应用程序将使用它。除此之外,其他一些.NETFramework类库也依赖于它。基本上,.NET核心应用程序已经制作完成,但后端

我在部分切换到.NET标准时遇到问题

我正在将类库迁移到.NET标准的过程中,在这个库中我有存储库和数据库通信。我已经成功地将其迁移到使用
AspNetCore.Identity.EntityFrameworkCore
。我试图实现的是最终有1个.NET标准项目负责数据库,其中1个MVC.NET Framework、1个API.NET Framework和1个新的.NET核心应用程序将使用它。除此之外,其他一些.NETFramework类库也依赖于它。基本上,.NET核心应用程序已经制作完成,但后端没有因为功能重叠而“合并”

小概览:

不将MVC/API转换为.Core的原因是,目前有太多其他库依赖于.NET Framework,有些库尚未转换,但对数据库使用相同的库是一个根本性的更改,这将避免某些存储库的双重实现

我还已经转换了实现
Microsoft.AspNetCore.Identity.IdentityUser
Microsoft.AspNetCore.Identity.IdentityRole
等的实体。 因此,我的DbContext类如下所示:

public class DatabaseContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationRoleClaim, ApplicationUserToken>
{
    private IConfiguration _config;
    public DatabaseContext(IConfiguration config) : base()
    {
        _config = config;
    }
    //all DbSet, OnModelCreating
}
嗯,我想这并没有多大用处,而且我在两个.NET Framework项目中都使用SimpleInjector,如果可能的话,我更愿意继续使用SimpleInjector,而不是使用默认的依赖项注入器

通过添加上面的内容,我真的不知道如何使用
ConfigureAuth
方法以及将所有配置放在哪里

当我尝试调整IdentityManager时,尝试在
AspNetCore.Identity
中引用相同的类型,在尝试更改
ApplicationUserManager
时,我开始遇到问题:

创建UserStore不是问题,但是尝试创建
UserManager
更困难,我也尝试在我的
UserRepository
中使用它,就像我以前做的那样,现在我不能再使用它了:(

旧用户存储库

private readonly UserManager<ApplicationUser, string> _userManager = null;
private readonly RoleManager<ApplicationRole, string> _roleManager = null;

internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
public UserRepository(DatabaseContext dbContext) : base(dbContext, c => c.contactId, m => m.ContactId)
{
    var userStore =
        new UserStore<ApplicationUser, ApplicationRole, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(dbContext);
    var roleStore = new RoleStore<ApplicationRole, string, ApplicationUserRole>(dbContext);
    _userManager = new UserManager<ApplicationUser, string>(userStore);
    _roleManager = new RoleManager<ApplicationRole, string>(roleStore);
    _userManager.UserValidator = new UserValidator<ApplicationUser>(_userManager) { AllowOnlyAlphanumericUserNames = false };
    if (DataProtectionProvider == null)
    {
        DataProtectionProvider = new MachineKeyProtectionProvider();
    }
    _userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, string>(DataProtectionProvider.Create("Identity"));
}
private readonly UserManager将它们放到那里当然我首先要解决根本问题


最后但并非最不重要的一点:请记住,这些应用程序都已投入生产,因此,特别是在用户周围,我需要确保所有登录都正常工作。当此版本上线时,由于其他一些迁移问题,我需要将数据迁移到新数据库。

好的,这是一个很长的答案,请做好准备o第二天花在把你的头发从你头上拔下来:)

首先是由两个不同类实现的
iaapplicationuser
接口:

public interface IApplicationUser
{
    string Id { get; set; }

    /// <summary>Gets or sets the user name for this user.</summary>
    string UserName { get; set; }
}
.NET Framework的实施:

public class IdentityManagerMvc : IIdentityManager
{
    private readonly UserManager<ApplicationUserMvc, string> _userManager = null;
    private readonly RoleManager<ApplicationRoleMvc, string> _roleManager = null;

    internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
    public IdentityManagerMvc(DatabaseContextMvc dbContext)
    {
        var userStore =
            new UserStore<ApplicationUserMvc, ApplicationRoleMvc, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(dbContext);
        var roleStore = new RoleStore<ApplicationRoleMvc, string, ApplicationUserRole>(dbContext);
        _userManager = new UserManager<ApplicationUserMvc, string>(userStore);
        _roleManager = new RoleManager<ApplicationRoleMvc, string>(roleStore);
        _userManager.UserValidator = new UserValidator<ApplicationUserMvc>(_userManager) { AllowOnlyAlphanumericUserNames = false };
        if (DataProtectionProvider == null)
        {
            DataProtectionProvider = new MachineKeyProtectionProvider();
        }
        _userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUserMvc, string>(DataProtectionProvider.Create("Identity"));
    }

    public async Task<IIdentityResult> CreateAsync(IApplicationUser user)
    {
        ApplicationUserMvc realUser = new ApplicationUserMvc()
        {
            Id = user.Id,
            TemporaryToken = user.TemporaryToken,
            AccessFailedCount = user.AccessFailedCount,
            ConcurrencyStamp = user.ConcurrencyStamp,
            Email = user.Email,
            EmailConfirmed = user.EmailConfirmed,
            LockoutEnabled = user.LockoutEnabled,
            LockoutEnd = user.LockoutEnd,
            NormalizedEmail = user.NormalizedEmail,
            NormalizedUserName = user.NormalizedUserName,
            PasswordHash = user.PasswordHash,
            PhoneNumber = user.PhoneNumber,
            PhoneNumberConfirmed = user.PhoneNumberConfirmed,
            RequiresPasswordCreation = user.RequiresPasswordCreation,
            SecurityStamp = user.SecurityStamp,
            TwoFactorEnabled = user.TwoFactorEnabled,
            UserName = user.UserName
        };
        var result = await _userManager.CreateAsync(realUser);
        return ConvertToInterface(result);
    }

    private IIdentityResult ConvertToInterface(IdentityResult result)
    {
        IIdentityResult realResult = new IdentityResultMvc();
        realResult.Succeeded = result.Succeeded;
        realResult.Errors = result.Errors?.ToList();
        return realResult;
    }
}


public class IdentityResultMvc : IdentityResult, IIdentityResult
{
    private IEnumerable<string> _errors;
    private bool _succeed;
    public new bool Succeeded
    {
        get => base.Succeeded || _succeed;
        set => _succeed = value;
    }

    public new List<string> Errors
    {
        get => base.Errors?.ToList() ?? _errors?.ToList();
        set => _errors = value;
    }
}
此时,您应该拥有在任何地方使用它所需的所有类。 例如,在.NET Framework项目中,您可以使用
ApplicationUserManager
如下所示:

public class ApplicationUserManager : UserManager<ApplicationUserMvc, string>
{
    public ApplicationUserManager(IUserStore<ApplicationUserMvc, string> store)
        : base(store)
    {//look at where i used applicationUserMvc
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var userStore =
            new UserStore<ApplicationUserMvc, ApplicationRoleMvc, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context.Get<DatabaseContextMvc>());
        //ApplicationUserLogin,UserRole,UserClaim are self created but just override IdentityUserLogin (for example).
        var manager = new ApplicationUserManager(userStore);
    }
  ...
}
您的重点可能已经在这篇长文章之后或在实施之后消失了,但还有几句话:

  • 我可以保证,有了这一点,你会使它工作,它的工作完美的过去半年
  • 因此.NET标准(以及EntityFrameworkCore)是执行数据库操作的主要方式,大多数代码都是为了处理.NET Framework
  • 您将努力安装正确的依赖项。它将导致运行时异常,您将很快遇到这些异常,但很容易解决,.NET Framework只需要为自己安装依赖项。确保版本对齐,使用Manage NuGet packages for Solution(右键单击Solution)下的Consolidate版本
  • 您必须以netcore的方式进行设置:因此在.NET Framework项目中也需要appsettings.json。您还需要在Web.Config中使用它,这主要用于身份验证的一小部分

    private IConfiguration GetConfiguartion()
    {
        var path = Server.MapPath("~/");
        var builder = new ConfigurationBuilder()
                         .SetBasePath(path)
                         .AddJsonFile("appsettings.json");
    
        return builder.Build();//inject the return IConfiguration in your DI
    }
    
  • 祝你好运。如果您认为这很困难并且会造成很多麻烦:正确,如果您有一个小型应用程序,那么最好将所有内容转换为.NET Core/.NET标准


我最终解决了这个问题,我会尽快更新答案,只是想知道你是怎么解决的?我有一个类似的场景,我们有一个提供管理系统的遗留应用程序,但我正在构建一个新的面向客户的.net core API,但需要在net core和net standard之间共享标识表,并且存在一些模式差异,即LockoutEndvs LockoutEndDateUtc。到目前为止,我的代码与上面的方法非常相似,但我还没有成功地使其正常工作yet@mcinnes01啊,看来我忘了在这里写答案了。今晚我会写这个。尽管很遗憾,我无法正确配置DataProtectionProvider,例如,重置密码只需在数据库用户表中存储一个令牌即可。我确实解决了在带有identity manager的.net core/framework和其他东西中使用1数据库上下文的问题。@mcinnes01我的答案已发布,希望您能理解。非常感谢,我将尝试一下:)
public interface IIdentityManager
{
    //User manager methods
    Task<IIdentityResult> CreateAsync(IApplicationUser user);
    //..all methods needed
}

public interface IIdentityResult
{
    bool Succeeded { get; set; }
    List<string> Errors { get; set; }
}
public class IdentityManagerCore : IIdentityManager
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly RoleManager<ApplicationRole> _roleManager;

    public IdentityManagerCore(UserManager<ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager)
    {
        _userManager = userManager;
        _roleManager = roleManager;
    }

    public async Task<IIdentityResult> CreateAsync(IApplicationUser user)
    {
        ApplicationUser realUser = new ApplicationUser()
        {
            Id = user.Id,
            TemporaryToken = user.TemporaryToken,
            AccessFailedCount = user.AccessFailedCount,
            ConcurrencyStamp = user.ConcurrencyStamp,
            Email = user.Email,
            EmailConfirmed = user.EmailConfirmed,
            LockoutEnabled = user.LockoutEnabled,
            LockoutEnd = user.LockoutEnd,
            NormalizedEmail = user.NormalizedEmail,
            NormalizedUserName = user.NormalizedUserName,
            PasswordHash = user.PasswordHash,
            PhoneNumber = user.PhoneNumber,
            PhoneNumberConfirmed = user.PhoneNumberConfirmed,
            RequiresPasswordCreation = user.RequiresPasswordCreation,
            SecurityStamp = user.SecurityStamp,
            TwoFactorEnabled = user.TwoFactorEnabled,
            UserName = user.UserName
        };
        var result = await _userManager.CreateAsync(realUser);
        return ConvertToInterface(result);
    }

    private IIdentityResult ConvertToInterface(IdentityResult result)
    {
        IIdentityResult realResult = new IdentityResultCore();
        realResult.Succeeded = result.Succeeded;
        realResult.Errors = result.Errors?.Select(x => x.Description).ToList();
        return realResult;
    }
}

public class IdentityResultCore : IdentityResult, IIdentityResult
{
       private IEnumerable<string> _errors;
    private bool _succeed;
    public new bool Succeeded
    {
        get => base.Succeeded || _succeed;
        set => _succeed = value;
    }

    public new List<string> Errors
    {
        get => base.Errors?.Select(x => x.Description).ToList() ?? _errors?.ToList();
        set => _errors = value;
    }
}
services.AddTransient<IIdentityManager, IdentityManagerCore>();
public class IdentityManagerMvc : IIdentityManager
{
    private readonly UserManager<ApplicationUserMvc, string> _userManager = null;
    private readonly RoleManager<ApplicationRoleMvc, string> _roleManager = null;

    internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
    public IdentityManagerMvc(DatabaseContextMvc dbContext)
    {
        var userStore =
            new UserStore<ApplicationUserMvc, ApplicationRoleMvc, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(dbContext);
        var roleStore = new RoleStore<ApplicationRoleMvc, string, ApplicationUserRole>(dbContext);
        _userManager = new UserManager<ApplicationUserMvc, string>(userStore);
        _roleManager = new RoleManager<ApplicationRoleMvc, string>(roleStore);
        _userManager.UserValidator = new UserValidator<ApplicationUserMvc>(_userManager) { AllowOnlyAlphanumericUserNames = false };
        if (DataProtectionProvider == null)
        {
            DataProtectionProvider = new MachineKeyProtectionProvider();
        }
        _userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUserMvc, string>(DataProtectionProvider.Create("Identity"));
    }

    public async Task<IIdentityResult> CreateAsync(IApplicationUser user)
    {
        ApplicationUserMvc realUser = new ApplicationUserMvc()
        {
            Id = user.Id,
            TemporaryToken = user.TemporaryToken,
            AccessFailedCount = user.AccessFailedCount,
            ConcurrencyStamp = user.ConcurrencyStamp,
            Email = user.Email,
            EmailConfirmed = user.EmailConfirmed,
            LockoutEnabled = user.LockoutEnabled,
            LockoutEnd = user.LockoutEnd,
            NormalizedEmail = user.NormalizedEmail,
            NormalizedUserName = user.NormalizedUserName,
            PasswordHash = user.PasswordHash,
            PhoneNumber = user.PhoneNumber,
            PhoneNumberConfirmed = user.PhoneNumberConfirmed,
            RequiresPasswordCreation = user.RequiresPasswordCreation,
            SecurityStamp = user.SecurityStamp,
            TwoFactorEnabled = user.TwoFactorEnabled,
            UserName = user.UserName
        };
        var result = await _userManager.CreateAsync(realUser);
        return ConvertToInterface(result);
    }

    private IIdentityResult ConvertToInterface(IdentityResult result)
    {
        IIdentityResult realResult = new IdentityResultMvc();
        realResult.Succeeded = result.Succeeded;
        realResult.Errors = result.Errors?.ToList();
        return realResult;
    }
}


public class IdentityResultMvc : IdentityResult, IIdentityResult
{
    private IEnumerable<string> _errors;
    private bool _succeed;
    public new bool Succeeded
    {
        get => base.Succeeded || _succeed;
        set => _succeed = value;
    }

    public new List<string> Errors
    {
        get => base.Errors?.ToList() ?? _errors?.ToList();
        set => _errors = value;
    }
}
public class DatabaseContextMvc : IdentityDbContext<ApplicationUserMvc, ApplicationRoleMvc, string, ApplicationUserLogin,
    ApplicationUserRole, ApplicationUserClaim>
{
    public DatabaseContextMvc() : base("DatabaseContext")
    {
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;

        //Database.SetInitializer<DatabaseContextMvc>(null);
    }

    public void SetTimeout(int minutes)
    {
        this.Database.CommandTimeout = minutes * 60;
    }

    public static DatabaseContextMvc Create()
    {
        return new DatabaseContextMvc();
    }
}
public class ApplicationUserManager : UserManager<ApplicationUserMvc, string>
{
    public ApplicationUserManager(IUserStore<ApplicationUserMvc, string> store)
        : base(store)
    {//look at where i used applicationUserMvc
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var userStore =
            new UserStore<ApplicationUserMvc, ApplicationRoleMvc, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(context.Get<DatabaseContextMvc>());
        //ApplicationUserLogin,UserRole,UserClaim are self created but just override IdentityUserLogin (for example).
        var manager = new ApplicationUserManager(userStore);
    }
  ...
}
public class DatabaseContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationRoleClaim, ApplicationUserToken>
{
    private IConfiguration _config;
    public string ConnectionString { get; }
    public DatabaseContext(IConfiguration config) : base()
    {
        _config = config;
        var connectionString = config.GetConnectionString("DatabaseContext");
        ConnectionString = connectionString;
    }

    public void SetTimeout(int minutes)
    {
        Database.SetCommandTimeout(minutes * 60);
    }

    public virtual DbSet<Address> Addresses { get; set; }

    public static DatabaseContext Create(IConfiguration config)
    {
        return new DatabaseContext(config);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        //setup code for the DbContextOptions
        optionsBuilder
            .UseSqlServer(ConnectionString, 
                providerOptions => providerOptions.CommandTimeout(60))
            .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
        base.OnConfiguring(optionsBuilder);
    }
private IConfiguration GetConfiguartion()
{
    var path = Server.MapPath("~/");
    var builder = new ConfigurationBuilder()
                     .SetBasePath(path)
                     .AddJsonFile("appsettings.json");

    return builder.Build();//inject the return IConfiguration in your DI
}