.NET + авторизация в ActiveDirectory
От: maxus78  
Дата: 16.08.10 05:37
Оценка:
Приветствую, коллеги!
Вопрос у меня такой:
Каждый пользователь, приходя утром на работу, вводит на своем компьютере пароль и авторизуется тем самым на сервере ActiveDirectory.
Соответственно, нужно организовать в конце дня сбор информации из AD — какой пользователь в какое время авторизовался и авторизовался ли вообще.
Эта информация должна быть получена из недр AD и занесена в базу данных MS SQL при помощи программы, написанной на .NET.
Соответственно, суть вопроса.
Какие библиотеки и классы задействовать для получения доступа к этой информации из AD и есть ли вообще возможность получить такую информацию от ActiveDirectory?
Re: .NET + авторизация в ActiveDirectory
От: Hussar77 Россия http://vstsblog.ru
Дата: 16.08.10 05:52
Оценка: 3 (1)
Здравствуйте, maxus78, Вы писали:

M>Приветствую, коллеги!

M>Вопрос у меня такой:
M>Каждый пользователь, приходя утром на работу, вводит на своем компьютере пароль и авторизуется тем самым на сервере ActiveDirectory.
M>Соответственно, нужно организовать в конце дня сбор информации из AD — какой пользователь в какое время авторизовался и авторизовался ли вообще.
M>Эта информация должна быть получена из недр AD и занесена в базу данных MS SQL при помощи программы, написанной на .NET.
M>Соответственно, суть вопроса.
M>Какие библиотеки и классы задействовать для получения доступа к этой информации из AD и есть ли вообще возможность получить такую информацию от ActiveDirectory?

Безусловно, такая возможность есть. Вам нужно воспользоваться классами из System.DirectoryServices Namespace (http://msdn.microsoft.com/en-us/library/system.directoryservices.aspx). Для Вашей конкретной задачи можно просто посмотреть значение атрибута Last-Logon (http://msdn.microsoft.com/en-us/library/ms676823.aspx) или Last-Logon-Timestamp (http://msdn.microsoft.com/en-us/library/ms676824.aspx).

Если хотите, всё это можно также сделать через PowerShell.
С уважением,
Владимир Гусаров aka Hussar
http://vstsblog.ru
Re: .NET + авторизация в ActiveDirectory
От: Sinix  
Дата: 16.08.10 06:01
Оценка: 9 (2)
Здравствуйте, maxus78, Вы писали:

M>Соответственно, нужно организовать в конце дня сбор информации из AD — какой пользователь в какое время авторизовался и авторизовался ли вообще.


По умолчанию в AD не ведётся аудит, если пользователь перелогинился несколько раз — запоминается последний вход в систему. Если устраивает, то смотрим обсуждение по теие
Автор:
Дата: 31.03.10
и FAQ по DirectoryServices.

Конкретно то, что просили:

http://msdn.microsoft.com/en-us/library/system.directoryservices.accountmanagement.authenticableprincipal.lastlogon(VS.90).aspx
Re: .NET + авторизация в ActiveDirectory
От: akisawa  
Дата: 06.12.10 15:55
Оценка:
Спасибо всем отвечавшим. Однако при использовании красивой функции UserPrincipal.FindByLogonTime LastLogon содержит устаревшее на несколько дней значение. Гляделка студии показывает более похожее на реальность значение в UserPrincipal.PermittedWorkstations.inner.LastChange, но два последних члена private, а конструктор, например, PermittedWorkstations -- internal. Никто не знает, как студия показывает это значение (как до него добраться)?
Re[2]: .NET + авторизация в ActiveDirectory
От: Sinix  
Дата: 06.12.10 18:14
Оценка:
Здравствуйте, akisawa, Вы писали:

A>Никто не знает, как студия показывает это значение (как до него добраться)?


Можно выгрести запросом через DirectorySearcher и посмотреть нужные свойства (см faq ).

Учтите, что результаты очень сильно зависят от политики домена и мании величия админа. Я бы не надеялся, что в любом домене вам вернут то, что попросите.
Re[3]: .NET + авторизация в ActiveDirectory
От: akisawa  
Дата: 07.12.10 11:10
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, akisawa, Вы писали:


A>>Никто не знает, как студия показывает это значение (как до него добраться)?


S>Можно выгрести запросом через DirectorySearcher и посмотреть нужные свойства (см faq ).


S>Учтите, что результаты очень сильно зависят от политики домена и мании величия админа. Я бы не надеялся, что в любом домене вам вернут то, что попросите.


А нельзя как-нибудь через WinNT, ведь Вы предлагаете через LDAP? У WinNT есть в свойствах логина LastLogin, а то, что предлагают мне админы даже имена логинов не содержит, только имена и фамилии пользователей, к которым по сорок с лишним свойств и ни одного подходящего.
Вообще на сервере ведётся протокол событий, там хранятся все попытки логона, успешные и неуспешные, судя по всему это не мессейджкью, так как таблицы сохраняются после перезагрузки (в SDK про это ничего нет).
Re: .NET + авторизация в ActiveDirectory
От: Lloyd Россия  
Дата: 07.12.10 11:16
Оценка: +1
Здравствуйте, maxus78, Вы писали:

M>Каждый пользователь, приходя утром на работу, вводит на своем компьютере пароль и авторизуется тем самым на сервере ActiveDirectory.


Это, кстати, не обязательно так. Если по каким-то причинам AD не доступен, юзер все равно сможет авторизоваться.
Re[4]: .NET + авторизация в ActiveDirectory
От: Sinix  
Дата: 07.12.10 11:51
Оценка:
Здравствуйте, akisawa, Вы писали:

S>>Можно выгрести запросом через DirectorySearcher и посмотреть нужные свойства (см faq ).


A>А нельзя как-нибудь через WinNT, ведь Вы предлагаете через LDAP? У WinNT есть в свойствах логина LastLogin, а то, что предлагают мне админы даже имена логинов не содержит, только имена и фамилии пользователей, к которым по сорок с лишним свойств и ни одного подходящего.


WinNT — это древняя как не знаю кто фигня, годящаяся разве что на домены NT 4.0 и на локальные запросы.
Очевидно, грабли или в разрешениях, или в коде. Вы код приведите — завтра может чего подскажу.

A>Вообще на сервере ведётся протокол событий, там хранятся все попытки логона, успешные и неуспешные, судя по всему это не мессейджкью, так как таблицы сохраняются после перезагрузки (в SDK про это ничего нет).

Где ведётся? И, если он ведётся — почему не взять эти данные?
Re[5]: .NET + авторизация в ActiveDirectory
От: akisawa  
Дата: 07.12.10 14:29
Оценка:
Здравствуйте, Sinix, Вы писали:


S>WinNT — это древняя как не знаю кто фигня, годящаяся разве что на домены NT 4.0 и на локальные запросы.

S>Очевидно, грабли или в разрешениях, или в коде. Вы код приведите — завтра может чего подскажу.

Вот код, который выдаёт логоны очень с большой задержкой (от нескольких дней):
PrincipalContext principalContext = null;
principalContext = new PrincipalContext(ContextType.Domain, "servername.domen.ru", "userName", "password");
PrincipalSearchResult<UserPrincipal> result = null;
result = UserPrincipal.FindByLogonTime(principalContext, DateTime.Now,
MatchType.LessThanOrEquals);
DataTable table = new DataTable();
table.Columns.Add("Имя", Type.GetType("System.String"));
table.Columns.Add("Logon", Type.GetType("System.DateTime"));
foreach (UserPrincipal user in result)
{
Nullable<DateTime> logon = user.LastLogon;
string name = user.Name;
//DateTime change = user.PermittedWorkstations.inner.LastChange;
if (user.Surname!=null && logon!=null)
{
DateTime local = logon.Value.ToLocalTime();
table.Rows.Add(name, local);
}
}
grid.DataSource = table;

Вот выдаёт получше:
String myADSPath = "WinNT://servername.domen.ru,computer";
DirectoryEntry m_drentry = new DirectoryEntry(myADSPath);
DirectoryEntry m_secentry = m_drentry.Children.Find("sovelyev");
DateTime lLogin = Convert.ToDateTime(m_secentry.Properties["LastChange"].Value);

А вот попытался по-Вашей подсказке (про OU=Test сказал администратор):
String myADSPath = "LDAP://servername.domen.ru/OU=Test,DC=DOMEN,DC=ru";
DirectorySearcher search = new DirectorySearcher(m_drentry);
search.Filter = "(objectClass=user)";
SearchResultCollection searchResults = search.FindAll();
foreach (SearchResult searchResult in searchResults)
{
DirectoryEntry user = searchResult.GetDirectoryEntry();
DateTime lLogin = Convert.ToDateTime(user.Properties["LastLogin"].Value); // Value=null
}


A>>Вообще на сервере ведётся протокол событий, там хранятся все попытки логона, успешные и неуспешные, судя по всему это не мессейджкью, так как таблицы сохраняются после перезагрузки (в SDK про это ничего нет).

S>Где ведётся? И, если он ведётся — почему не взять эти данные?
Windows Server 2003, администрирование -> просмотр событий (можно зайти через управление компьютером) -> безопасть: ведётся журнал событий в формате файл.evt, номер сообщения о логоне 540.
Re[6]: .NET + авторизация в ActiveDirectory
От: Sinix  
Дата: 07.12.10 15:27
Оценка:
Здравствуйте, akisawa, Вы писали:

A>Вот код, который выдаёт логоны очень с большой задержкой (от нескольких дней):

Ок, завтра посмотрю.

A>Windows Server 2003, администрирование -> просмотр событий (можно зайти через управление компьютером) -> безопасть: ведётся журнал событий в формате файл.evt, номер сообщения о логоне 540.


Тогда вам нужен EventLog, или, если вам повезло и сервер у вас — 2008й, EventLogQuery.

Конечно, через LDAP оно понадёжнее, но и так сойдёт.
Re[6]: .NET + авторизация в ActiveDirectory
От: Sinix  
Дата: 08.12.10 03:03
Оценка:
Здравствуйте, akisawa, Вы писали:

A>Вот код, который выдаёт логоны очень с большой задержкой (от нескольких дней):


А так:
      DirectorySearcher ds = new DirectorySearcher(
        Domain.GetCurrentDomain().GetDirectoryEntry());

      ds.Filter = "(objectClass=user)";
      // необязательно.
      ds.PropertiesToLoad.AddRange(new[] { "samaccountname", "lastlogontimestamp" });

      foreach (SearchResult searchResult in ds.FindAll())
      {
        // если надо другие свойства:
        // 1. убираем ds.PropertiesToLoad.AddRange...
        // 2. ставим брякпойнт и смотрим через watch содержимое searchResult.Properties

        Console.WriteLine((string)searchResult.Properties["samaccountname"][0]);
        Console.WriteLine(DateTime.FromFileTime((long)searchResult.Properties["lastlogontimestamp"][0]));
      }
Re[7]: .NET + авторизация в ActiveDirectory
От: akisawa  
Дата: 08.12.10 10:08
Оценка: 8 (1)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, akisawa, Вы писали:


A>>Вот код, который выдаёт логоны очень с большой задержкой (от нескольких дней):


S>А так:

S>
S>      DirectorySearcher ds = new DirectorySearcher(
S>        Domain.GetCurrentDomain().GetDirectoryEntry());

S>      ds.Filter = "(objectClass=user)";
S>      // необязательно.
S>      ds.PropertiesToLoad.AddRange(new[] { "samaccountname", "lastlogontimestamp" });

S>      foreach (SearchResult searchResult in ds.FindAll())
S>      {
S>        // если надо другие свойства:
S>        // 1. убираем ds.PropertiesToLoad.AddRange...
S>        // 2. ставим брякпойнт и смотрим через watch содержимое searchResult.Properties

S>        Console.WriteLine((string)searchResult.Properties["samaccountname"][0]);
S>        Console.WriteLine(DateTime.FromFileTime((long)searchResult.Properties["lastlogontimestamp"][0]));
S>      }
S>


Спасибо за помощь, я тут чуть-чуть подправил (у нас не один контроллер в домене и нужны только OU=Test), но выдаваемые даты как у меня с UserPrincipal, то есть с большей задержкой, чем у WinNT. Сейчас тестирую EventLog. Данные есть, там таймштампы стоят по несколько штук в день на логин, всё подходит, один минус -- доступ очень медленный (мои логины программа искала почти час). Так что буду брать пользователей через Ваш пример, а их таймштампы через анализ (а он только построчный) ивентлога. Спасибо ещё раз. Хотя очень печально, что UserPrincipal не соджержит нормального времени.
Re[8]: .NET + авторизация в ActiveDirectory
От: Sinix  
Дата: 08.12.10 11:20
Оценка:
Здравствуйте, akisawa, Вы писали:


A>Спасибо за помощь, я тут чуть-чуть подправил (у нас не один контроллер в домене и нужны только OU=Test), но выдаваемые даты как у меня с UserPrincipal, то есть с большей задержкой, чем у WinNT.


Однозначно у вас что-то не то с AD. У нас таймштампы актуальные. Посмотрите остальные свойства, может, найдёте что-нить.

A>Сейчас тестирую EventLog. Данные есть, там таймштампы стоят по несколько штук в день на логин, всё подходит, один минус -- доступ очень медленный (мои логины программа искала почти час).


Да, оно безбожно тормозит. Можно попробовать через WMI (сам не пробовал). Доменный сервер у вас не Win2008?
Re[9]: .NET + авторизация в ActiveDirectory
От: akisawa  
Дата: 08.12.10 14:05
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, akisawa, Вы писали:



A>>Спасибо за помощь, я тут чуть-чуть подправил (у нас не один контроллер в домене и нужны только OU=Test), но выдаваемые даты как у меня с UserPrincipal, то есть с большей задержкой, чем у WinNT.


S>Однозначно у вас что-то не то с AD. У нас таймштампы актуальные. Посмотрите остальные свойства, может, найдёте что-нить.


A>>Сейчас тестирую EventLog. Данные есть, там таймштампы стоят по несколько штук в день на логин, всё подходит, один минус -- доступ очень медленный (мои логины программа искала почти час).


S>Да, оно безбожно тормозит. Можно попробовать через WMI (сам не пробовал). Доменный сервер у вас не Win2008?


Контроллеры (сервера) у нас все 2003. Но проблема решена. Accounts собираем через LDAP, а LastLogin берём максимальный из всех контроллеров через WinNT, этот штамп актуален. Ваш метод не проверял по всем контроллерам, а UserPrincipal не актуален.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.