Reputation: 29
I created Asp.Net Mvc web application w/c is using windows authentication. My requirement is capture and log invalid login attempts but don't know how to do it. Tried to google but no luck.
Here is what i tried so far. Using below code,
List item It fires after 3 invalid attempts in IE but don't know how to get user name input. Global.asax
protected void Application_EndRequest(Object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context.Response.Status.Substring(0, 3).Equals("401"))
{
//Capture user name for further processing
//
context.Response.ClearContent();
context.Response.Write("You are un authorized ");
}
}
Thanks in advance, hope someone can help.
Upvotes: 1
Views: 1280
Reputation: 29
Finally made it work, totally get rid of my first code using Application_EndRequest event.
Thanks to derloopkat.
Code on Global.asax Session_Start event.
protected void Session_Start(object sender, EventArgs e)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
string currentUser = HttpContext.Current.User.Identity.Name;
Int32 expiryMin = Convert.ToInt32(ConfigurationManager.AppSettings["CacheExpirationInMinutes"]);
// call our procedure
auditLog(currentUser);
bool IsActive = accessMaintenance.IsActive(currentUser);
if (IsActive)
{
// handling if user is valid/not locked...
}
else
{
// Other handling if user is locked...
}
}
}
auditLog Procedure
private void auditLog(string user)
{
// Get logs from event viewer
string userName = ExtractUserAlias(user);
EventLog securityLog = new EventLog("Security");
var logOnAttempts = (
from log in securityLog.Entries.Cast<EventLogEntry>()
where log.EventID == 4625 || log.EventID== 4624 && log.ReplacementStrings[5] == userName
orderby log.TimeGenerated descending
select log
).Take(20).ToList();
//Store user logs to db if logs does not exists.
//Store in DB for reporting purposes
DataAccess db = new DataAccess();
foreach (var x in logOnAttempts)
{
string entryType = "";
switch (x.EntryType)
{
case EventLogEntryType.SuccessAudit:
entryType = "SuccessAudit";
break;
case EventLogEntryType.FailureAudit:
entryType = "FailureAudit";
break;
}
SqlCommand com = new SqlCommand();
com.CommandType = System.Data.CommandType.StoredProcedure;
com.CommandText = "Sp_LogUser";
com.Parameters.AddWithValue("@UserName", userName);
com.Parameters.AddWithValue("@EntryType", entryType);
com.Parameters.AddWithValue("@TimeGenerated", x.TimeGenerated);
com.Parameters.AddWithValue("@Details", x.Message);
db.ExecuteNonQuery(com);
}
// logic to to validate and lock user
SqlCommand com2 = new SqlCommand();
com2.CommandType = System.Data.CommandType.StoredProcedure;
com2.CommandText = "Sp_validateAndLockUser";
com2.Parameters.AddWithValue("@Username", @userName);
db.ExecuteNonQuery(com2);
}
Upvotes: 1
Reputation: 6683
Windows is already capturing and logging invalid logon attempts in Windows Event Log. This can be seen using the application Event Viewer
under Windows Logs/Security
. But we also can retrieve these logs using C#.
Open Visual Studio as administrator and add this code. Just for testing we're going to get last 10 records.
EventLog securityLog = new EventLog("Security");
var logOnAttempts = (from log in securityLog.Entries.Cast<EventLogEntry>()
where log.EntryType==EventLogEntryType.SuccessAudit
orderby log.TimeGenerated descending
select log
).Take(10).ToList();
Property Message
of my last log says:
A logon was attempted using explicit credentials.
Subject:
Security ID: S-1-5-21-3657345512-3965846940-1053971979-1002
Account Name: Daniel_2
Account Domain: Acer
Logon ID: 0x29058
Account Whose Credentials Were Used:
Account Name: jjjjj
Account Domain:
Where "jjjjj" is the user name I typed when trying to log into the page, and Daniel_2 is my Windows account. This value can be easily extracted by means of property ReplacementStrings
. In my case ReplacementStrings[5]
gets me "jjjjj". I think the query for EventLog entries needs to be filtered by application and date time, so it only shows logons to your web application once it's deployed in IIS.
Upvotes: 0