Это, безусловно, ошибка в коде. NET, и я отвечу на ваш вопрос, но, как я уже упоминал в вашем другом вопросе, мартовское обновление не будет «разрешать только безопасные вызовы с использованием LDAPS». Обычный порт LDAP 389 все еще будет работать после этого обновления. Я не видел доказательств того, что они когда-либо планируют отключить его.
Но если вы хотите убедиться, что он никогда не использует порт 389, вы не будете использовать UserPrincipal
. Используйте DirectoryEntry
и / или DirectorySearcher
напрямую, что в любом случае UserPrincipal
использует в фоновом режиме. Это не первая найденная ошибка в пространстве имен AccountManagement
.
Я написал статью о поиске всех групп пользователей , в которой есть пример кода для разных сценариев ios. Вам придется изменить любой случай, когда вы создаете новый DirectoryEntry
объект и указываете порт 636, например:
new DirectoryEntry("LDAP://example.com:636/CN=whatever,DC=example,DC=com")
Вы можете фактически опустить доменное имя, если хотите (просто :636
вместо example.com:636
).
Один случай, который я не рассмотрел в этой статье, эквивалентен GetAuthorizationGroups
, то есть чтению атрибута tokenGroups
. Это дает вам список идентификаторов безопасности групп, которые вы затем можете найти, чтобы найти название группы. Вот метод, который будет делать это:
private static IEnumerable<string> GetTokenGroups(DirectoryEntry de) {
var groupsFound = 0;
//retrieve only the tokenGroups attribute from the user
de.RefreshCache(new[] {"tokenGroups"});
while (true) {
var tokenGroups = de.Properties["tokenGroups"];
foreach (byte[] groupSidByte in tokenGroups) {
groupsFound++;
var groupSid = new SecurityIdentifier(groupSidByte, 0);
var groupDe = new DirectoryEntry($"LDAP://:{de.Options.PasswordPort}/<SID={groupSid}>");
groupDe.RefreshCache(new[] {"cn"});
yield return (string) groupDe.Properties["cn"].Value;
}
//AD only gives us 1000 or 1500 at a time (depending on the server version)
//so if we've hit that, go see if there are more
if (tokenGroups.Count != 1500 && tokenGroups.Count != 1000) break;
try {
de.RefreshCache(new[] {$"memberOf;range={groupsFound}-*"});
} catch (COMException e) {
if (e.ErrorCode == unchecked((int) 0x80072020)) break; //no more results
throw;
}
}
}
, который будет использовать любой порт, который вы использовали для создания объекта DirectoryEntry
, который вы передаете. Однако, это ломается, если у вас более одного домена в вашем окружающая обстановка. В этом случае все может быть сложно, если вы хотите всегда использовать порт 636.