1

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.

  1. List item How to capture user name input from authentication popup?
  2. List item Is there setting to limit login pop up after consecutive login failed. It works on Internet Explorer (IE),It display 401 unauthorized after 3 consecutive login attempts but Firefox and Mozilla do not have limits.

Here is what i tried so far. Using below code,

  • List item I'm trying to capture unauthorized error unfortunately event only fire when i click cancel for Firefox and Mozilla.
  • 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.

2
  • I believe logon user should be in HttpContext.Current.Request.ServerVariables["LOGON_USER"] but since login was unsuccessful then access is anonymous. Perhaps this situation requires a different approach. Commented Nov 21, 2017 at 12:00
  • derloopkat I tried ServerVariables["LOGON_USER"] but still empty. thank for the reply Commented Nov 22, 2017 at 6:28

2 Answers 2

1

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);
    
    }
    
Sign up to request clarification or add additional context in comments.

Comments

0

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.

3 Comments

Thanks for the info sir really helpful, i can now extract the logs but i really need user name during login because my requirement is to disable them real time for consecutive invalid attempts.
When detecting "unauthorised access" Http 401 in Application_EndRequest(), they can be blocked real time at this point based on Event Logs properly filtered. Creating your own log is reinventing the wheel. If your requirement is displaying an error message, then allow Windows to validate user and password first, after successful logon check Event Log and block the user, log him out and redirect to error page "your account is blocked".
Thanks so much derloopkat, nice idea and i believe this will do the trick. I’ll post my final code once done.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.