[英]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.