问题
I'm trying to lock user login after 3 unsuccessful login attempts for 5 minutes. I have add this 3 lines to App_Start/IdentityConfig.cs
public static ApplicationUserManager Create( ... )
method:
manager.MaxFailedAccessAttemptsBeforeLockout = 3;
manager.DefaultAccountLockoutTimeSpan = new TimeSpan(0, 5, 0);
manager.UserLockoutEnabledByDefault = true;
After that I register new user via POST /api/Account/Register
(in default scaffolded AccountController
). Account is created and LockoutEnabled
property is set to true
. But if I try to login for via POST /Token
few times with wrong password account isn't locked down.
I'm also interested where is implementation of /Token
endpoint. Is it in AccountController
GET api/Account/ExternalLogin
. I have set breakpoint there but execution wasn't stopped there when I tried to login.
What am I missing?
回答1:
If you are using the default Web API template from Visual Studio, you have to change the behavior of GrantResourceOwnerCredentials
method of the ApplicationOAuthProvider
class (found inside the Provider folder of your Web API project). Something like this could allow you to track failed login attempts, and stop locked out users from logging in:
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await userManager.FindByNameAsync(context.UserName);
if (user == null)
{
context.SetError("invalid_grant", "Wrong username or password."); //user not found
return;
}
if (await userManager.IsLockedOutAsync(user.Id))
{
context.SetError("locked_out", "User is locked out");
return;
}
var check = await userManager.CheckPasswordAsync(user, context.Password);
if (!check)
{
await userManager.AccessFailedAsync(user.Id);
context.SetError("invalid_grant", "Wrong username or password."); //wrong password
return;
}
await userManager.ResetAccessFailedCountAsync(user.Id);
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
Be aware that this way you can only lock out users trying to login using the password
grant (Resource Owner Credentials). If you also want to disallow locked out user to login using other grants, you have to override the other methods (GrantAuthorizationCode
, GrantRefreshToken
, etc.), checking if await userManager.IsLockedOutAsync(user.Id)
is true in those methods too.
来源:https://stackoverflow.com/questions/36447153/identity-framework-user-lockdown