【问题标题】:.NET - Check user/password against Active Directory without locking account.NET - 在不锁定帐户的情况下根据 Active Directory 检查用户/密码
【发布时间】:2017-10-06 12:49:07
【问题描述】:

我需要根据一个 aspx 表单的活动目录验证用户。问题是:如果我尝试使用错误的密码登录 5 次,则此帐户将被锁定。

有什么方法可以检查用户/密码是否有效而不会浪费登录尝试?

PD:我一直在想,如果我可以使用管理员帐户登录 perharps,它可以检查另一个用户/密码是否有效。这可能吗?如果这是可能的,我该怎么做?

提前谢谢你。

【问题讨论】:

    标签: .net login active-directory block account


    【解决方案1】:

    你想要的都是不可能的。帐户锁定由域控制。锁定之前允许的不成功登录数量以及锁定将持续多长时间由域中的组策略选项配置。无论您使用什么机制来验证域的用户名和密码,失败的尝试都会导致对该帐户的标记。

    如果可以通过编程方式绕过此机制,那么该机制将毫无价值。

    编辑:可以在域中禁用帐户锁定机制,但它会非常不安全,尤其是当您使用 Web 表单验证域凭据时。没有它,我可以包装您的表单并使用它来暴力破解域密码。如果您要求域管理员禁用它,您的域管理员会嘲笑您离开他的办公室 :)

    【讨论】:

    • 我不得不同意。 AD 策略控制在指定数量的无效登录情况下的锁定机制。
    • 非常感谢您的回答。如果不可能,我必须尝试另一种方式。
    • 我不知道为什么这被否决(我刚刚添加了 +1)。不能绕过锁定机制是正确的。
    【解决方案2】:

    我知道很老了,但为什么不保留一个单独的简单数据库表,其中包含用户和密码列表。它可以被加密或其他。

    首先使用网页登录过程检查该表,如果其中存在凭据,则继续实际登录 AD。

    【讨论】:

      【解决方案3】:

      我处理的要求与您指定的类似。我们编写了以下类来检查身份验证 -

      using System;
      using System.Runtime.InteropServices;
      
      namespace ADApps.Common
      {
          /// <summary>
          /// Provide functions for testing Logon of user. 
          /// Reference - <see href="http://stackoverflow.com/questions/1394025/active-directory-ldap-check-account-locked-out-password-expired">Active Directory (LDAP) - Check account locked out / Password expired</see>
          /// </summary>
          class WinApi
          {
              [DllImport("advapi32.dll", SetLastError = true)]
              static public extern bool LogonUser(string principal, string authority, string password, LogonTypes logonType, LogonProviders logonProvider, out IntPtr token);
      
              [DllImport("kernel32.dll", SetLastError = true)]
              static public extern bool CloseHandle(IntPtr handle);
          }
      
          enum LogonTypes : uint
          {
              Interactive = 2,
              Network = 3,
              Batch = 4,
              Service = 5,
              Unlock = 7,
              NetworkCleartext = 8,
              NewCredentials = 9
          }
          enum LogonProviders : uint
          {
              Default = 0, // default for platform (use this!)
              WinNT35,     // sends smoke signals to authority
              WinNT40,     // uses NTLM
              WinNT50      // negotiates Kerb or NTLM
          }
      
          enum Errors
          {
              ErrorPasswordMustChange = 1907,
              ErrorLogonFailure = 1326,
              ErrorAccountRestriction = 1327,
              ErrorAccountDisabled = 1331,
              ErrorInvalidLogonHours = 1328,
              ErrorNoLogonServers = 1311,
              ErrorInvalidWorkstation = 1329,
              ErrorAccountLockedOut = 1909,      //It gives this error if the account is locked, REGARDLESS OF WHETHER VALID CREDENTIALS WERE PROVIDED!!!
              ErrorAccountExpired = 1793,
              ErrorPasswordExpired = 1330
          }
      }
      

      以及以下验证用户的方法-

              /// <summary>
              /// Authenticates a user against Active Directory
              /// </summary>
              /// <param name="domain">The domain</param>
              /// <param name="userName">The username</param>
              /// <param name="password">The password</param>
              /// <returns>A boolean indicated valid user authentication</returns>
              public static bool IsAuthenticated(string domain, string userName, string password)
              {
                  var isAuthenticated = false;
                  var token = new IntPtr();
      
                  try
                  {
                      if (!WinApi.LogonUser(userName, domain, password, LogonTypes.Network,
                          LogonProviders.Default, out token))
                      {
                          var errorType = (Errors)Marshal.GetLastWin32Error();
      
                          switch (errorType)
                          {
                              case Errors.ErrorLogonFailure:
                                  throw new Exception("Invalid username or password");
                              case Errors.ErrorPasswordExpired:
                                  isAuthenticated = true;
                                  break;
                          }
                      }
                      else
                      {
                          isAuthenticated = true;
                      }
                  }
                  finally
                  {
                      WinApi.CloseHandle(token);
                  }
      
                  return isAuthenticated;
              }
      

      请尝试验证用户的方法并让我们知道您的测试结果。希望一切顺利。

      【讨论】:

      • 这不会阻止帐户被锁定。
      • 我试过了,效果很好!可悲的是,它花费了身份验证尝试。无论如何,非常感谢维克拉姆的帮助! ;)
      猜你喜欢
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 2019-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多