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