Это продолжение до моего предыдущего вопроса .
Вопрос
Как правильно проверить учетные данные, переданные PrincipalContext
?
Фон
В моем приложении я создаю PrincipalContext
, используя PrincipalContext(ContextType, String, String, String)
. У меня есть ряд интеграционных тестов, которые не выполняются, когда учетные данные неверны (или предоставленные учетные данные не для администратора), поэтому я хочу иметь возможность это перехватить.
Если учетные данные недействительны, PrincipalContext.ConnectedServer
выдает System.DirectoryServices.DirectoryServicesCOMException
, однако это не обнаруживается до первого использования PrincipalContext.
try
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "my_domain.local", "wrong_username", "wrong_password");
}
catch (exception e)
{
// This block is not hit
}
// `System.DirectoryServices.DirectoryServicesCOMException` raised here
using (UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, samAccountName)) {}
Сведения об исключении:
System.DirectoryServices.DirectoryServicesCOMException
HResult=0x8007052E
Message=The user name or password is incorrect.
Source=System.DirectoryServices
StackTrace:
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.PropertyValueCollection.PopulateList()
at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)
Что я пробовал
Первоначально я думал проверить учетные данные при создании, однако, если мы повторно используем PrincipalContext
с другими учетными данными, мы получим System.DirectoryServices.Protocols.LdapException
.
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "my_domain.local", "correct_username", "correct_password");
if (ctx.ValidateCredentials("correct_username", "correct_password"))
{
// `System.DirectoryServices.Protocols.LdapException` raised here
using (UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, different_user)) {}
}
Сведения об исключении:
System.DirectoryServices.Protocols.LdapException
HResult=0x80131500
Message=The LDAP server is unavailable.
Source=System.DirectoryServices.Protocols
StackTrace:
at System.DirectoryServices.Protocols.ErrorChecking.CheckAndSetLdapError(Int32 error)
at System.DirectoryServices.Protocols.LdapSessionOptions.FastConcurrentBind()
at System.DirectoryServices.AccountManagement.CredentialValidator.BindLdap(NetworkCredential creds, ContextOptions contextOptions)
at System.DirectoryServices.AccountManagement.CredentialValidator.Validate(String userName, String password)
at System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials(String userName, String password)
Какой правильный подход?
Есть ли приемлемый способ проверить это? Должен ли я попытаться присвоить PrincipalContext.ConnectedServer
локальной переменной и перехватить исключение?