[英]C# - Windows authentication - How to get from HttpContext user's Full doMain name (FQDN)
[英]Get the full windows domain name from a session id
我正在研究需要監視Windows會話更改並在特定用戶登錄后自動啟動應用程序的服務應用程序。
這是它的工作方式,我有一個文件,其中包含以用戶主體名稱格式(user@domain.LOCAL)存儲的Windows用戶名列表。 我的服務將監視任何會話更改,並在其中一個用戶登錄后采取某些措施。
List<string> _UsersList;
object _sessionCheckLock = new object();
void OnCheckSession(int nSessionId, bool bIsLoggIn)
{
lock(_sessionCheckLock)
{
try
{
string sUserName = string.Empty;
string sDomain = string.Empty;
IntPtr pUserName = IntPtr.Zero;
uint nBytesReturned = 0;
if (WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSUserName, out pUserName, out nBytesReturned) && (pUserName != IntPtr.Zero))
{
sUserName = Marshal.PtrToStringAnsi(pUserName);
WTSFreeMemory(pUserName);
IntPtr pDomain = IntPtr.Zero;
if(WTSQuerySessionInformation(IntPtr.Zero, (uint)nSessionId, WTS_INFO_CLASS.WTSDomainName, out pDomain, out nBytesReturned) && (pDomain != IntPtr.Zero))
{
sDomain = Marshal.PtrToStringAnsi(pDomain);
WTSFreeMemory(pDomain);
}
else
{
}
if (!string.IsNullOrEmpty(sUserName))
{
if(!string.IsNullOrEmpty(sDomain)
{
sUserName += "@" + sDomain;
}
foreach(string username in _UsersList)
{
if(string.Compare(sUsername, username, true)==0)
{
//Do a couple of things
return;
}
}
}
}
else
{
return;
}
}
catch (System.Exception ex)
{
}
}
}
上面的代碼是每當引發新的登錄事件時我調用的函數。 _UsersList是一個字符串列表,其中包含允許該服務使用的所有用戶名。 這里的問題是WTSQuerySessionInformation
與WTS_INFO_CLASS.WTSDomainName
使用時不返回域的全名,因此比較失敗。例如,如果用戶列表中存在一個名為(username@DOMAIN.LOCAL)的用戶名並登錄,查詢會話的域名時,它僅返回(DOMAIN),而沒有.LOCAL附錄。 我需要找到一種方法來獲取完整的域名以匹配列表中的域名。
有人可以幫忙嗎
查看Cassia.Net,這是非常有用的。
您可以下載源代碼,我將其用於一個項目,在該項目中,我必須獲取所有已登錄到服務器的用戶。
決明子.NET Windows終端服務/遠程桌面服務庫
http://code.google.com/p/cassia/
希望能有所幫助
WTsmainName顯示用戶所屬的域-我找不到任何明確的文檔,但是我認為它獲取的是netBios名稱,而不是FQDN。 您應該能夠使用USERDNSDOMAIN和USERDOMAIN這兩個環境變量來保存這些值。
您也可以使用ADSI進行更詳細的查找,在此處查看線程
但這一切都說明了,除非您擁有一個令人難以置信的復雜林結構,並且用戶從樹中的許多不同域中登錄,否則...將轉換硬編碼到您的應用中可能會更快。 它們並不是經常更改的東西,從新域登錄的用戶也應該很少。
紅蛇,決明子真的有幫助嗎? 我遇到了與您相同的問題,但是Cassia似乎在下面使用了相同的WTSQuerySessionInformation
調用,因此我仍然只得到了簡短的域名。
在此頁面上,我找到了對DsGetDcName
函數的引用,我可以使用該函數使用WTSQuerySessionInformation
給我的短域名獲取FQDN。 這是適合我的示例:
std::wstring GetSessionDomainName(DWORD sessionId)
{
std::wstring domainName;
LPWSTR buffer = NULL;
DWORD bufferSize = 0;
if(WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSDomainName, &buffer, &bufferSize))
{
PDOMAIN_CONTROLLER_INFOW domainControllerInfo = NULL;
DWORD retVal = DsGetDcNameW(NULL, buffer, NULL, NULL, DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME, &domainControllerInfo);
if (retVal == 0)
domainName = domainControllerInfo->DnsForestName;
WTSFreeMemory(buffer);
NetApiBufferFree(domainControllerInfo);
}
return domainName;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.