之前遇到了一个问题,就是包里使用到了IdentityOptions
Lockout.MaxFailedAccessAttempts
Lockout.DefaultLockoutTimeSpan
我需要通过配置文件写入这个Options
1、第一步,我是考虑通过ConfigreServices的
Configure<IdentityOptions>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromSeconds(10);
});
去配置的,但是包里的值并没有改变 ,这个试了很多次,无论把代码写在Post里都不行
context.Services.AddIdentityCore<IdentityUser>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
options.Lockout.AllowedForNewUsers = true;
});
PreConfigure<IdentityOptions>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromSeconds(10);
});
Configure<IdentityOptions>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromSeconds(10);
});
PostConfigure<IdentityOptions>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromSeconds(10);
});
2、第二步,我是考虑通过ReplaceService的方式,实在没办法的情况下才用的,因为我知道这个肯定可以把功能实现,但是不完美
public class IdentityUserLockoutOptions
{
/// <summary>
/// 最大用户登录错误次数
/// </summary>
public int MaxUserLoginErrorCount { get; set; }
/// <summary>
/// 用户锁定分钟数
/// </summary>
public int UserLockoutMinutes { get; set; }
}
Configure<IdentityUserLockoutOptions>(options =>
{
options.MaxUserLoginErrorCount = 10;
options.UserLockoutMinutes = 10;
});
我自定义了一个IdentityUserLockoutOptions,在一下方法中注入使用它,然后替换服务
[Dependency(ReplaceServices = true)]
public class CustomUserManager<TUser> : UserManager<TUser> where TUser : class
{
public IdentityUserLockoutOptions IdentityUserLockoutOptions { get; set; }
public CustomUserManager(IUserStore<TUser> store,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<TUser> passwordHasher,
IEnumerable<IUserValidator<TUser>> userValidators,
IEnumerable<IPasswordValidator<TUser>> passwordValidators,
ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors,
IServiceProvider services, ILogger<UserManager<TUser>> logger,
IOptions<IdentityUserLockoutOptions> identityUserLockoutOptionsAccessor) : base(store,
optionsAccessor,
passwordHasher,
userValidators,
passwordValidators,
keyNormalizer,
errors,
services,
logger)
{
IdentityUserLockoutOptions = identityUserLockoutOptionsAccessor?.Value ?? new IdentityUserLockoutOptions();
}
public override Task<IdentityResult> AccessFailedAsync(TUser user)
{
Options.Lockout.MaxFailedAccessAttempts = IdentityUserLockoutOptions.MaxUserLoginErrorCount;
Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(IdentityUserLockoutOptions.UserLockoutMinutes);
return base.AccessFailedAsync(user);
}
}
context.Services.TryAddScoped<CustomUserManager<IdentityUser>>();
context.Services.Replace(ServiceDescriptor.Scoped<UserManager<IdentityUser>, CustomUserManager<IdentityUser>>());
这样就顺利把值传入base的方法中了,问题是我们其实并没有改变注入的IdentityOptions的值
3、第三步,我找啊找啊
找啊
找到了一个方法
我们需要自定义一个IdentityOptionManager的类去继承AbpDynamicOptionsManager 去修改IdentityOptions的值
public class CustomIdentityOptionsManager : AbpDynamicOptionsManager<IdentityOptions>
{
public CustomIdentityOptionsManager(IOptionsFactory<IdentityOptions> factory, IConfiguration configuration) : base(factory)
{
Configuration = configuration;
}
protected IConfiguration Configuration { get; }
protected override Task OverrideOptionsAsync(string name, IdentityOptions options)
{
var maxUserLoginErrorCount = 5; var userLockoutMinutes = 5;
//这里读configuration的配置修改maxUserLoginErrorCount ,userLockoutMinutes
options.Lockout.MaxFailedAccessAttempts = maxUserLoginErrorCount;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(userLockoutMinutes);
return Task.CompletedTask;
}
}
需要AbpVnext再AbpModule中添加AbpDynamicOptions
public override void PostConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDynamicOptions<Microsoft.AspNetCore.Identity.IdentityOptions, CustomIdentityOptionsManager>();
}
第三种方法很完美,修改了IdentityOptions的值