簡體   English   中英

.NET-在不鎖定帳戶的情況下對照Active Directory檢查用戶/密碼

[英].NET - Check user/password against Active Directory without locking account

我需要從aspx表單針對活動目錄驗證用戶。 這是問題所在:如果我嘗試使用錯誤的密碼登錄5次,該帳戶將被鎖定。

有沒有辦法在沒有浪費登錄嘗試的情況下檢查用戶/密碼是否有效?

PD:我一直在想,如果我可以使用管理員帳戶perharps登錄,則可以檢查其他用戶/密碼是否有效。 這可能嗎? 如果可能的話,我該怎么辦?

先感謝您。

您想要的是不可能的。 帳戶鎖定由域控制。 鎖定之前允許的失敗登錄數量以及鎖定將持續多長時間由域中的組策略選項配置。 無論您使用哪種機制針對域驗證用戶名和密碼,嘗試失敗都會導致對該帳戶進行標記。

如果可以以編程方式繞過此機制,則該機制將毫無價值。

編輯:帳戶鎖定機制可以在域中禁用,但這將是非常不安全的,尤其是當您具有驗證域憑據的Web表單時。 沒有它,我可以包裝您的表單並將其用於蠻力破解域密碼。 如果您要求域管理員將其禁用,則您的域管理員會在您辦公室外嘲笑您:

我很老,但是為什么不保留一個單獨的簡單數據庫表,其中包含用戶和密碼列表。 它可以加密或其他方式。

使用網頁登錄過程首先檢查該表,然后在其中檢查憑據,然后繼續實際登錄到AD。

我按照與您指定的要求類似的要求進行工作。 我們編寫了以下課程來檢查身份驗證-

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

請嘗試使用該方法來驗證用戶身份,並讓我們知道您的測試結果。 我希望它能正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM