ローカル マシンまたはドメインのいずれかで 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;
}
}
}