【问题标题】:Asp.net MVC Capture user name from authentication popupAsp.net MVC 从身份验证弹出窗口中捕获用户名
【发布时间】:2017-11-21 10:44:05
【问题描述】:

我创建的 Asp.Net Mvc Web 应用程序 w/c 使用 Windows 身份验证。 我的要求是捕获并记录无效的登录尝试,但不知道该怎么做。尝试谷歌,但没有运气。

  1. 列表项 如何从身份验证弹出窗口中捕获用户名输入?
  2. 列表项 是否有设置限制连续登录失败后弹出登录。 它适用于 Internet Explorer (IE),连续 3 次登录尝试后显示 401 未授权,但 Firefox 和 Mozilla 没有限制。

这是我到目前为止所尝试的。 使用下面的代码,

  • 列表项 我正在尝试捕获未经授权的错误,不幸的是,只有在我点击 Firefox 和 Mozilla 的取消时才会触发事件。
  • 列表项 它在 IE 中 3 次无效尝试后触发,但不知道如何获取用户名输入。 全球.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 ");
        }
    }
    

先谢谢了,希望有人能帮忙。

【问题讨论】:

  • 我相信登录用户应该在HttpContext.Current.Request.ServerVariables["LOGON_USER"],但由于登录不成功,所以访问是匿名的。也许这种情况需要不同的方法。
  • derloopkat 我试过 ServerVariables["LOGON_USER"] 但仍然是空的。谢谢回复

标签: c# asp.net asp.net-mvc asp.net-mvc-4 windows-authentication


【解决方案1】:

终于让它工作了,完全摆脱了我使用 Application_EndRequest 事件的第一个代码。

感谢 derloopkat。

  • Global.asax Session_Start 事件的代码。

    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...
    
            }
    
        }
    }
    
  • 审计日志程序

    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);
    
    }
    

【讨论】:

    【解决方案2】:

    Windows 已经在 Windows 事件日志中捕获和记录无效登录尝试。这可以使用Windows Logs/Security 下的应用程序Event Viewer 看到。但我们也可以使用 C# 检索这些日志。

    以管理员身份打开 Visual Studio 并添加此代码。仅用于测试,我们将获得最后 10 条记录。

    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();
    

    我上次日志的属性Message 说:

    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:     
    

    其中“jjjjj”是我在尝试登录页面时输入的用户名,Daniel_2 是我的 Windows 帐户。该值可以通过属性ReplacementStrings 轻松提取。在我的情况下,ReplacementStrings[5] 让我“jjjjj”。我认为 EventLog 条目的查询需要按应用程序和日期时间进行过滤,因此它仅在部署到 IIS 后才显示对您的 Web 应用程序的登录。

    【讨论】:

    • 感谢先生提供的信息真的很有帮助,我现在可以提取日志,但我在登录时确实需要用户名,因为我的要求是在连续无效尝试时实时禁用它们。
    • 当检测到Application_EndRequest()中的“未经授权的访问”Http 401时,可以根据正确过滤的事件日志在此时实时阻止它们。创建自己的日志是在重新发明轮子。如果您的要求是显示错误消息,则允许 Windows 首先验证用户和密码,成功登录后检查事件日志并阻止用户,将他注销并重定向到错误页面“您的帐户被阻止”。
    • 非常感谢 derloopkat,好主意,我相信这会成功。完成后我会发布我的最终代码。
    猜你喜欢
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-21
    • 2021-10-25
    • 2020-08-28
    • 1970-01-01
    相关资源
    最近更新 更多