Запись в каталоге передана с учетными данными, не использованными для изменений фиксации - PullRequest
1 голос
/ 11 апреля 2019

Я создаю веб-приложение, которое подключается к Active Directory и позволяет пользователям редактировать свои собственные данные в Active Directory из приложения.

Пользователи могут видеть сведения о других пользователях, поэтому приложение использует проверку подлинности Windows только для разрешенияредактирование собственных данных пользователя.Очевидно, что я не могу предоставить каждому пользователю права администратора, чтобы разрешить это, поэтому при настройке записи каталога я передаю ей учетные данные для учетной записи службы администратора.

При достижении изменений фиксации я вижу, что учетные данные ADEntry верны,Однако, по-видимому, он не использует переданные учетные данные и вместо этого использует учетные данные проверки подлинности Windows.

Когда пользователь с правами администратора запускает приложение, он может изменить данные, но когда пользователь без прав администратора запускает приложение, он получает ошибку- Доступ запрещен - при достижении CommitChanges ().Это заставляет меня поверить, что он использует учетные данные для проверки подлинности Windows, а не те, которые указаны в DirectoryEntry (учетные данные)

Есть идеи?Нужно ли использовать олицетворение?

DirectoryEntry ADEntry()
{
    using (DirectoryEntry ADEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure))

        {
            return ADEntry;
        }
}

DirectorySearcher ADSearcher()
{
    using(DirectorySearcher ADSearcher = new DirectorySearcher(ADEntry()))
    {
        return ADSearcher;
    }
}

SearchResult GetADSearchResult(string userToFind)
{
    SearchResult searchResult = new SearchResult();
    DirectorySearcher ADS = ADSearcher();
    ADS.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
    searchResult = ADS.FindOne();
    return searchResult;
}

void SetProperty(string userToFind, string propertyToChange, string newPropertyValue)
{
    SearchResult searchResult = GetADSearchResult(userToFind);
    DirectoryEntry _ADEntry = searchResult.GetDirectoryEntry();
    if (_ADEntry.Properties.Contains(propertyToChange))
    {  
        _ADEntry.Properties[propertyToChange].Remove(_ADEntry.Properties[propertyToChange].Value);
    }
    _ADEntry.Properties[propertyToChange].Insert(0, newPropertyValue);
    _ADEntry.CommitChanges();
}

1 Ответ

1 голос
/ 11 апреля 2019

Эти методы создают, немедленно удаляют, а затем возвращают некоторые экземпляры объекта:

DirectoryEntry ADEntry()
{
    using (DirectoryEntry ADEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure))
    {
        return ADEntry;
    }
}

DirectorySearcher ADSearcher()
{
    using(DirectorySearcher ADSearcher = new DirectorySearcher(ADEntry()))
    {
        return ADSearcher;
    }
}

Итак, это:

...
DirectorySearcher ADS = ADSearcher();
ADS.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
searchResult = ADS.FindOne();
...

... можно эффективно перевести на это:

var directoryEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure);
directoryEntry.Dispose();

var directorySearcher = = new DirectorySearcher(directoryEntry);
directorySearcher.Dispose();

directorySearcher.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
var searchResult = directorySearcher.FindOne();

К сожалению, у меня нет AD для тестирования, и, возможно, это не является основной причиной вашей проблемы.Однако я бы порекомендовал исправить код, чтобы не использовать экземпляры объектов после их удаления.Следующий подход может быть лучшим подходом:

SearchResult searchResult;
using (var directoryEntry = new DirectoryEntry(myDomain, myAdminServiceUsername, myAdminServicePassword, AuthenticationTypes.Secure))
using (var directorySearcher = new DirectorySearcher(directoryEntry))
{
    directorySearcher.Filter = "(&(objectClass=user)(sAMAccountname=" + userToFind + "))";
    searchResult = directorySearcher.FindOne();
}

// It's OK to use searchResult here, it's not `IDisposable`.
...