Simple login protection for ASP.NET applications
Posted: (EET/GMT+2)
If your ASP.NET application has a public login page, assume that automated login attempts will eventually find it.
This does not always mean a targeted attack. Many bots simply scan the Internet and try common usernames and passwords against anything that looks like a login form.
A good first step in ASP.NET Core is rate limiting the login endpoint.
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(options =>
{
options.AddFixedWindowLimiter("login", limiter =>
{
limiter.Window = TimeSpan.FromMinutes(1);
limiter.PermitLimit = 5;
limiter.QueueLimit = 0;
});
});
WebApplication app = builder.Build();
app.UseRateLimiter();
app.MapPost("/login", async (LoginRequest request) =>
{
// validate username and password here
return Results.Ok();
})
.RequireRateLimiting("login");
app.Run();
This limits how often the login endpoint can be called during a short time window.
Tip: rate limiting slows down automated hammering, but it is not authentication by itself. Keep the normal password checks, account rules, and audit logging in place.
If you use ASP.NET Core Identity, also configure lockout settings:
builder.Services.Configure<IdentityOptions>(options =>
{
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Lockout.AllowedForNewUsers = true;
});
Account lockout helps protect individual accounts after repeated failed attempts.
However, do not rely on lockout alone. An attacker can also abuse lockout to prevent real users from signing in.
Logging is also important. Store enough information to investigate failed login attempts:
- username
- IP address
- user agent
- timestamp
- success or failure.
Never log passwords, reset tokens, or authentication cookies.
For public applications, also consider protection in front of the application:
- reverse proxy rules
- Azure Front Door WAF
- Application Gateway WAF
- IIS Dynamic IP Restrictions
- Cloudflare or similar edge protection.
Blocking obvious abuse before it reaches ASP.NET is usually better than handling everything inside the application.
Also keep login error messages boring:
Invalid username or password.
Avoid messages that reveal whether the username exists or only the password was wrong.
For administrator accounts and other important users, enable multi-factor authentication. Rate limiting slows attackers down. MFA changes the result even if the password is guessed.
So: start with rate limiting, lockout, logging, and MFA. Those four protections already raise the cost of automated login attempts significantly.