SetPassword
устанавливает атрибут unicodePwd
. Это имеет некоторые ограничения на то, когда оно может быть обновлено. Документация для этого гласит:
Серверы операционной системы Windows 2000 требуют, чтобы клиент имел 128-битное (или лучше) SSL / TLS-зашифрованное соединение с DC, чтобыизменить этот атрибут. В операционной системе Windows Server 2003 и более поздних версиях контроллер домена также позволяет изменять атрибут unicodePwd в соединении, защищенном 128-разрядным (или лучше) шифрованием на уровне простой аутентификации и уровня безопасности (SASL) вместо SSL / TLS.
Он должен установить безопасное соединение по умолчанию (это делает для меня), но вполне возможно, что он не может в вашей настройке по любой причине.
Вы можете передать ContextOptions
объект в конструкторе вашего PrincipalContext
. По умолчанию автоматически устанавливается значение ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing
, которое должно быть безопасным. Но ContextOptions.Negotiate
использует «либо Kerberos, либо NTLM», а ContextOptions.Signing
(шифрование) зависит от Kerberos. Поэтому, возможно, он возвращается к NTLM и не может зашифровать.
Вы могли бы быть в состоянии подтвердить это, проверив следующие значения после создания учетной записи:
Console.WriteLine(ctx.Options);
Console.WriteLine(((DirectoryEntry) usr.GetUnderlyingObject()).AuthenticationType);
Значения, которые вы ищете:
Negotiate, Signing, Sealing
Secure, Signing, Sealing
Это то, что я имею, когда SetPassword
работает. Но я не уверен, что он действительно изменит эти значения, если вернется к NTLM. Иногда это происходит довольно тихо.
В любом случае, если Kerberos не происходит, вы можете либо устранить это, либо попытаться подключиться через LDAPS (LDAP через SSL). Это выглядело бы примерно так:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
Environment.GetEnvironmentVariable("DOMAIN") + ":636",
Environment.GetEnvironmentVariable("USER_OU"),
ContextOptions.Negotiate | ContextOptions.SecureSocketLayer,
Environment.GetEnvironmentVariable("SERVICE_USERNAME"),
Environment.GetEnvironmentVariable("SERVICE_PASSWORD"));
Но это может вызвать другие проблемы, так как ваш DC должен иметь сертификат, которому вы доверяете.