使Identtiy核心选项可通过数据库进行配置

时间:2018-12-17 06:53:53

标签: c# .net asp.net-core asp.net-identity

我是ASPNET核心的新手。我们正在使用身份核心2.1。现在制作了一个页面,管理员可以在其中设置不同的配置,例如空闲时间锁定时间密码重试。这些设置将保存到数据库表中。现在,我希望从这些值中设置我的身份选项。我建立了一个存储库以从数据库获取设置。但是我无法从startup.cs调用该存储库功能。

可以请一些指导我吗?并且还告诉我使数据库中的身份选项可配置的最佳方法。

我已经提供服务

public class SecuritySettingService : ISecuritySettingService
{
    private readonly ISecuritySettingRepository _securitySettingRepository;
    public SecuritySettingService(ISecuritySettingRepository securitySettingRepository)
    {
        _securitySettingRepository = securitySettingRepository;
    }
    public SecuritySetting GetSecuritySetting()
    {
       return  _securitySettingRepository.GetSecuritySetting();
    }
}

用于连接数据库的存储库

public class SecuritySettingRepository : ISecuritySettingRepository
{
    private readonly IDbRepository _dapperWrapper;
    public SecuritySettingRepository(IDbRepository dapperWrapper)
    {
        _dapperWrapper = dapperWrapper;
    }
    public SecuritySetting GetSecuritySetting()
    {
        var response = _dapperWrapper.QuerySingleOrDefault<SecuritySetting>("security_setting_get", null, CommandType.StoredProcedure);

        return response;
    }
}

制作了身份配置类以清理startup.cs

公共静态类IdentityConfig     {         公共静态无效的ConfigureIdentity(IServiceCollection服务,ISecuritySettingService securitySettingService)         {

        var securitySetting = securitySettingService.GetSecuritySetting();
        services.AddIdentity<ApplicationUser, ApplicationRole>(options => {
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequireLowercase = true;


        }).AddUserManager<CustomUserManager>().AddDefaultTokenProviders();





        services.Configure<IdentityOptions>(options =>
        {
            // Default User settings.
            options.User.AllowedUserNameCharacters =
                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
            options.User.RequireUniqueEmail = true;


        });

        services.Configure<DataProtectionTokenProviderOptions>(options =>
        {
            options.TokenLifespan = TimeSpan.FromDays(30);
        });

        services.ConfigureApplicationCookie(options =>
        {
            options.Cookie.HttpOnly = true;
            options.ExpireTimeSpan = TimeSpan.FromHours(1);
            options.LoginPath = "/login";
            options.LogoutPath = "/logout";
            options.Cookie = new CookieBuilder
            {
                IsEssential = true // required for auth to work without explicit user consent; adjust to suit your privacy policy
            };
        });

    }
}

startup.cs文件就像

public class Startup
{
    public ISecuritySettingService _securitySettingService;
    public Startup(IConfiguration configuration, ISecuritySettingService securitySettingService)
    {
        Configuration = configuration;
        _securitySettingService = securitySettingService;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {



        IdentityConfig.ConfigureIdentity(services, _securitySettingService);


        services.AddOptions();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

        services.AddHttpContextAccessor();

    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {

    }
}
当我调用IdentityConfig.ConfigureIdentity(services,_securitySettingService)时在startup.cs中

;对象_securitySettingService不存在,所以我的代码引发异常无效操作

1 个答案:

答案 0 :(得分:0)

对于您当前的错误,您是否注册了ISecuritySettingService并在Startup中使用了它。要引用ISecuritySettingService,您需要先注册。

对于services.Configure<IdentityOptions>,它在更改数据库时不会自动更改。您需要自己更新IdentityOptions

按照以下步骤操作,并根据需要对其进行修改。

  1. ISecuritySettingRepository

    public interface ISecuritySettingRepository
    {
        LockoutOption GetSecuritySetting();
        LockoutOption UpdateSecuritySetting(LockoutOption lockoutOption);
    }
    
  2. SecuritySettingRepository

    public class SecuritySettingRepository : ISecuritySettingRepository
    {
        private readonly DbConnection _dapperWrapper;
        private readonly IConfiguration _configuration;
    
        public SecuritySettingRepository(DbConnection dapperWrapper
            , IConfiguration configuration)
        {
            _dapperWrapper = dapperWrapper;
            _configuration = configuration;
        }
        public LockoutOption GetSecuritySetting()
        {
            using (var connection = new SqlConnection(_configuration.GetConnectionString("DefaultConnection")))
            {
                string sQuery = "SELECT top 1 * From LockoutOption Where Id = 1";
                var response = connection.QueryFirstOrDefault<LockoutOption>(sQuery);
                return response;
            }
        }
    
        public LockoutOption UpdateSecuritySetting(LockoutOption lockoutOption)
        {
            using (var connection = new SqlConnection(_configuration.GetConnectionString("DefaultConnection")))
            {
                string sQuery = $"Update LockoutOption Set MaxFailedAccessAttempts = {lockoutOption.MaxFailedAccessAttempts} Where Id = {lockoutOption.Id}";
                var result = connection.Execute(sQuery);
                string sQuery1 = "SELECT top 1 * From LockoutOption Where Id = 1";
                var response = connection.QueryFirstOrDefault<LockoutOption>(sQuery1);
    
                return response;
            }
        }
    }
    
  3. ISecuritySettingService

    public interface ISecuritySettingService
    {
        LockoutOption GetSecuritySetting();
        LockoutOption UpdateSecuritySetting(LockoutOption lockoutOption);
    }
    
  4. SecuritySettingService

    public class SecuritySettingService : ISecuritySettingService
    {
        private readonly ISecuritySettingRepository _securitySettingRepository;
        private readonly IdentityOptions _identityOptions;
    
        public SecuritySettingService(ISecuritySettingRepository securitySettingRepository
            , IOptions<IdentityOptions> identityOptions)
        {
            _securitySettingRepository = securitySettingRepository;
            _identityOptions = identityOptions.Value;
        }
        public LockoutOption GetSecuritySetting()
        {
            return _securitySettingRepository.GetSecuritySetting();
        }
    
        public LockoutOption UpdateSecuritySetting(LockoutOption lockoutOption)
        {
            var option = _securitySettingRepository.UpdateSecuritySetting(lockoutOption);
            //update identity options
            _identityOptions.Lockout.MaxFailedAccessAttempts = option.MaxFailedAccessAttempts;
            return option;
        }
    }
    
  5. Startup中注册

    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<DbConnection>(serviceProvider => new DbConnection(Configuration.GetConnectionString("DefaultConnection")));
            services.AddMvc();
            // your rest configure services
    
            services.AddTransient<ISecuritySettingService, SecuritySettingService>();
            services.AddTransient<ISecuritySettingRepository, SecuritySettingRepository>();
            var _ecuritySettingService = services.BuildServiceProvider().GetRequiredService<ISecuritySettingService>();
            services.Configure<IdentityOptions>(options =>
            {
                options.Lockout.MaxFailedAccessAttempts = _ecuritySettingService.GetSecuritySetting()?.MaxFailedAccessAttempts ?? 3;
            });
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            //your configure
        }
    }
    
  6. 使用情况

    namespace DapperPro.Controllers
    {
        public class LockoutOptionsController : Controller
        {
            private readonly ApplicationDbContext _context;
            private readonly IdentityOptions _identityOptions;
            private readonly ISecuritySettingService _securitySettingService;
            public LockoutOptionsController(ApplicationDbContext context
                , IOptions<IdentityOptions> identityOptions
                , ISecuritySettingService securitySettingService)
            {
                _context = context;
                _identityOptions = identityOptions.Value;
                _securitySettingService = securitySettingService;
            }        
    
            // POST: LockoutOptions/Edit/5
            // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
            // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> Edit(int id, [Bind("Id,AllowedForNewUsers,MaxFailedAccessAttempts,DefaultLockoutTimeSpan")] LockoutOption lockoutOption)
            {
                _securitySettingService.UpdateSecuritySetting(lockoutOption);
    
                return View(lockoutOption);
            }        
        }
    }