Identity Framework User Lockdown

╄→尐↘猪︶ㄣ 提交于 2020-07-21 03:55:26

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!