在 Y 次无效尝试后锁定 ASP.NET 登录用户 X 分钟并且 userManager.IsLockedOutAsync 为假
Lock ASP.NET login user for X minutes after Y invalid attempts and userManager.IsLockedOutAsync is false
我正在开发 asp.net 网络 api 项目并尝试实现在 Y 次无效尝试后将用户登录锁定 X 分钟的功能。
我已经在身份配置中设置了这个
// Enable Lock outs
manager.MaxFailedAccessAttemptsBeforeLockout = 1;
manager.DefaultAccountLockoutTimeSpan = new TimeSpan(0, 5, 0);
manager.UserLockoutEnabledByDefault = true;
在IdentityConfig.cs
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true,
};
// Enable Lock outs
manager.MaxFailedAccessAttemptsBeforeLockout = 1;
manager.DefaultAccountLockoutTimeSpan = new TimeSpan(0, 5, 0);
manager.UserLockoutEnabledByDefault = true;
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
manager.EmailService = new EmailServiceCustom();
int Token = 24;
if (ConfigurationManager.AppSettings["TokenLifespan"] != null
)
{
Token = Convert.ToInt32(ConfigurationManager.AppSettings["TokenLifespan"]);
}
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = System.TimeSpan.FromHours(Token)
};
}
return manager;
}
并在 OAuthProvider.cs Class
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
//context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await userManager.FindByNameAsync(context.UserName).ConfigureAwait(false);
//var user= await context.OwinContext.GetUserManager<ApplicationUserManager>()
// .FindAsync(context.UserName, context.Password).ConfigureAwait(false);
if (user == null)
{
context.SetError("invalid_grant", "The user name is incorrect.");
return;
}
if (await userManager.IsLockedOutAsync(user.Id))
{
context.SetError("locked_out", "User is locked out");
return;
}
if (!await userManager.IsEmailConfirmedAsync(user.Id))
{
context.SetError("invalid_grant", "You need to confirm your email.");
return;
}
var check = await userManager.CheckPasswordAsync(user, context.Password);
if (!check)
{
await userManager.AccessFailedAsync(user.Id);
context.SetError("invalid_grant", "The password is incorrect."); //wrong password
return;
}
ClaimsIdentity oAuthIdentity = await (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).GenerateUserIdentityAsync(userManager, "JWT").ConfigureAwait(false);
var userForCheck = this.userService.GetUserById((await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Id);
AuthenticationTicket ticket;
if ((oAuthIdentity.IsAuthenticated && userForCheck == null) ||
oAuthIdentity.IsAuthenticated && userForCheck.status)
{
var claims = new List<Claim>();
var roles = await userManager.GetRolesAsync((await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Id).ConfigureAwait(false);
claims.AddRange(roles.Select(role => new Claim("role", role)));
claims.Add(new Claim("unique_name", (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).UserName));
claims.Add(new Claim("email", (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Email));
oAuthIdentity.AddClaims(claims);
ticket = new AuthenticationTicket(oAuthIdentity, null);
context.Validated(ticket);
}
}
但是 user.LockoutEnabled 是 false 并且 userManager.IsLockedOutAsync(user.Id)
即使在无效尝试之后也返回 false。我在这里做错了什么?
我得到了 的帮助,但仍然是同样的问题
如果有人偶然发现这个问题:
如果您在实施锁定功能之前创建了用户,UserLockoutEnabledByDefault
将被忽略。这是因为默认值仅在值 (UserLockOut) 为空时适用。但是这个 属性 设置为 false。
因此,您需要进行一次性更改以将锁定设置为 true(仅限现有用户)。 e.g await userManager.SetLockoutEnabledAsync(user.Id, true);
我正在开发 asp.net 网络 api 项目并尝试实现在 Y 次无效尝试后将用户登录锁定 X 分钟的功能。
我已经在身份配置中设置了这个
// Enable Lock outs
manager.MaxFailedAccessAttemptsBeforeLockout = 1;
manager.DefaultAccountLockoutTimeSpan = new TimeSpan(0, 5, 0);
manager.UserLockoutEnabledByDefault = true;
在IdentityConfig.cs
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true,
};
// Enable Lock outs
manager.MaxFailedAccessAttemptsBeforeLockout = 1;
manager.DefaultAccountLockoutTimeSpan = new TimeSpan(0, 5, 0);
manager.UserLockoutEnabledByDefault = true;
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
manager.EmailService = new EmailServiceCustom();
int Token = 24;
if (ConfigurationManager.AppSettings["TokenLifespan"] != null
)
{
Token = Convert.ToInt32(ConfigurationManager.AppSettings["TokenLifespan"]);
}
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = System.TimeSpan.FromHours(Token)
};
}
return manager;
}
并在 OAuthProvider.cs Class
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
//context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await userManager.FindByNameAsync(context.UserName).ConfigureAwait(false);
//var user= await context.OwinContext.GetUserManager<ApplicationUserManager>()
// .FindAsync(context.UserName, context.Password).ConfigureAwait(false);
if (user == null)
{
context.SetError("invalid_grant", "The user name is incorrect.");
return;
}
if (await userManager.IsLockedOutAsync(user.Id))
{
context.SetError("locked_out", "User is locked out");
return;
}
if (!await userManager.IsEmailConfirmedAsync(user.Id))
{
context.SetError("invalid_grant", "You need to confirm your email.");
return;
}
var check = await userManager.CheckPasswordAsync(user, context.Password);
if (!check)
{
await userManager.AccessFailedAsync(user.Id);
context.SetError("invalid_grant", "The password is incorrect."); //wrong password
return;
}
ClaimsIdentity oAuthIdentity = await (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).GenerateUserIdentityAsync(userManager, "JWT").ConfigureAwait(false);
var userForCheck = this.userService.GetUserById((await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Id);
AuthenticationTicket ticket;
if ((oAuthIdentity.IsAuthenticated && userForCheck == null) ||
oAuthIdentity.IsAuthenticated && userForCheck.status)
{
var claims = new List<Claim>();
var roles = await userManager.GetRolesAsync((await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Id).ConfigureAwait(false);
claims.AddRange(roles.Select(role => new Claim("role", role)));
claims.Add(new Claim("unique_name", (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).UserName));
claims.Add(new Claim("email", (await userManager.FindAsync(context.UserName, context.Password).ConfigureAwait(false)).Email));
oAuthIdentity.AddClaims(claims);
ticket = new AuthenticationTicket(oAuthIdentity, null);
context.Validated(ticket);
}
}
但是 user.LockoutEnabled 是 false 并且 userManager.IsLockedOutAsync(user.Id)
即使在无效尝试之后也返回 false。我在这里做错了什么?
我得到了
如果有人偶然发现这个问题:
如果您在实施锁定功能之前创建了用户,UserLockoutEnabledByDefault
将被忽略。这是因为默认值仅在值 (UserLockOut) 为空时适用。但是这个 属性 设置为 false。
因此,您需要进行一次性更改以将锁定设置为 true(仅限现有用户)。 e.g await userManager.SetLockoutEnabledAsync(user.Id, true);