0

我有一个应用程序需要能够对本地计算机或域使用 Windows 身份验证。以前,我使用的是PrincipalContext.ValidateCredentials,起初它工作正常,然后它开始随机返回 false 以获得正确的凭据。我看了这个问题,看到人们说如果PrincipalContext.ValidateCredentials负载过重,那么它可能会开始抛出异常,我注意到其他地方人们说它总是返回错误。

我链接的问题建议使用图书馆中LogonUser的代替。advapi32.dll没关系,唯一的问题是我希望能够PrincipalContext.ValidateCredentials在说另一种方法有效之前可靠地中断呼叫。此代码不会产生任何错误,并且永远不会在返回这些误报的同一系统上返回 false。我想打破它,这样我就可以确保LogonUser通话不会出现同样的问题。

using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestAuthentication
{
    class Program
    {
        static void Main(string[] args)
        {
            var credentials = new Dictionary<string, string>
            {
                {"Developer","rfsdev"},
                {"Customer","password"},
                {"Content Builder", "password"},
            };
            bool isBroken = false;
            int maxTries = 10000;
            int currentTry = 0;
            while(!isBroken && currentTry < maxTries)
            {
                currentTry++;
                foreach(var kvp in credentials)
                {
                    isBroken = !AreCredentialsValid(kvp.Key, kvp.Value);
                    Console.WriteLine("Result from {0} and {1}: {2}", kvp.Key, kvp.Value, !isBroken);
                    if (isBroken)
                    {
                        Console.WriteLine("Found breaking case after {0} tries", currentTry);
                        break;
                    }
                }
            }
            Console.ReadLine();
        }

        protected static bool AreCredentialsValid(string username, string password)
        {
            bool isDomain = username.Contains("\\");
            string domain = isDomain ? username.Split(new char[] { '\\' })[0] : "";
            username = isDomain ? username.Split(new char[] { '\\' })[1] : username;
            bool credentialsValid = false;
            if (isDomain)
                using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
                    credentialsValid = pc.ValidateCredentials(username, password);
            else
                using (PrincipalContext pc = new PrincipalContext(ContextType.Machine))
                    credentialsValid = pc.ValidateCredentials(username, password);
            return credentialsValid;
        }
    }
}
4

0 回答 0