add a block after 4 wrong password and/or login attempts and unblock the connection after a sometime

wiss user 20 Reputation points
2024-03-05T16:09:24.75+00:00

Hello,

I work on web application asp.net mvc .net 4.8.

In order to add a block after 4 wrong password and/or login attempts and unblock after some time. I wanted to modify Login Action.

We don't want to use aspNet Identity because we didn't want to add a column on the database side.

I need a solution using session/cache or variable store count.

Thanks in advance.

`[HttpPost]`

[AllowAnonymous]

[ValidateAntiForgeryToken]

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)

{

if (!ModelState.IsValid)

{

return View(model);

}

var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);

switch (result)

{

case SignInStatus.Success:

var user = await UserManager.FindByNameAsync(model.UserName);

HttpCookie partnerInfo = new HttpCookie("User#" + user.Id);

partnerInfo["FullName"] = user.FullName;

Response.Cookies.Add(partnerInfo);

return RedirectToLocal(returnUrl);

case SignInStatus.LockedOut:

ModelState.AddModelError("", "Account Blocked. Try after some time.");

return View("model");

case SignInStatus.RequiresVerification:

return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });

case SignInStatus.Failure:

default:

ModelState.AddModelError("", "Invalid login attempt.");

}

model.NotConnect = true;

return View(model);

}

}

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,265 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,272 questions
{count} votes

Accepted answer
  1. Lan Huang-MSFT 25,636 Reputation points Microsoft Vendor
    2024-03-07T03:30:28.7633333+00:00

    Hi @wiss user,

    Based on your description, I tested a simple example about session, you can refer to it.

    public ActionResult Login()
    {
        return View();
    }
    private static int cntAttemps = 0;
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Login(UserProfile objUser)
    {
        if (ModelState.IsValid)
        {
            using (TestContext db = new TestContext())
            {
                var obj = db.UserProfile.Where(a => a.UserName.Equals(objUser.UserName) && a.Password.Equals(objUser.Password)).FirstOrDefault();
                if (obj != null)
                {
                    if (Session["Message"] == null)
                    {
                        cntAttemps = 1;
                        Session["UserID"] = obj.UserId.ToString();
                        Session["UserName"] = obj.UserName.ToString();
                        return RedirectToAction("UserDashBoard");
                    }
                }
                else
                {
                    InvalidLoginAttemps();
                }
            }
        }
        return View(objUser);
    }
    private void InvalidLoginAttemps()
    {
        try
        {
            cntAttemps++;
            Session["count"] = cntAttemps.ToString();
            ModelState.AddModelError("", "Invalid login attempt.");
            if (Convert.ToInt32(Session["count"]) > 3)
            {
                Session["Message"] = "Account Blocked. Try after some time.";
                //code to block user
            }
        }
        catch (Exception ex)
        {
        }
    }
    public ActionResult UserDashBoard()
    {
        return View();
    }
    
    @model WebMvc.Models.UserProfile
    @{
        ViewBag.Title = "Login";
    }
    @using (Html.BeginForm("Login", "Home", FormMethod.Post))
    {
        <fieldset>
            <legend>Mvc Simple Login Application Demo</legend>
            @Html.AntiForgeryToken()
            @Html.ValidationSummary(true)
            @if (Session["Message"] != null)
            {
                <p style="border: 1px solid
    red">
                    @Session["Message"]
                </p>
            }
          
            <table>
                <tr>
                    <td>@Html.LabelFor(a => a.UserName)</td>
                    <td>@Html.TextBoxFor(a => a.UserName)</td>
                    <td>@Html.ValidationMessageFor(a => a.UserName)</td>
                </tr>
                <tr>
                    <td>@Html.LabelFor(a => a.Password)</td>
                    <td>@Html.PasswordFor(a => a.Password)</td>
                    <td>@Html.ValidationMessageFor(a => a.Password)</td>
                </tr>
                <tr>
                    <td></td>
                    <td><input type="submit" value="Login" /></td>
                    <td></td>
                </tr>
            </table>
        </fieldset>
    }
    
     <system.web>
       <compilation debug="true" targetFramework="4.8" />
       <httpRuntime targetFramework="4.8" />
      <sessionState timeout="2"></sessionState>
     </system.web>
    

    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


2 additional answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 56,686 Reputation points
    2024-03-05T16:27:02.3866667+00:00

    while adding a column is the best choice, you can add a database table keyed by login and has the count. as a session cookie expires when the browser is closed, if you wanted to use a cookie solution, then use a persistent cookie (but the user could still delete, or use different browser/machine).


  2. wiss user 20 Reputation points
    2024-03-08T11:04:06.84+00:00

    Thank you so much for your help.

    After 3 invalid connection attempts, I cleaned the session after 10 min.

    I connect with the correct email/word, I got this as an error.==. System.Web.Mvc.HttpAntiForgeryException

    HResult=0x80004005

    Message=Anti-Forgery Token was meant for a different claims-based user

    Any idea ?

    I can switch that after rebuilding the solution.

    0 comments No comments