如何从 Windows 服务中托管的 Web 服务获取用户的 Active Directory 组
How to get the user's Active Directory groups from web service hosted in a Windows service
我有一个在服务器上存储文档的 Web 应用程序。在某些情况下,我需要为每个用户组设置某些权限,因为它们存储在 Active Directory 中。
我在服务器上的 Windows 服务中设置了托管的 Web 服务,服务器正在与该 Web 服务联系以获取数据。
当我从常规控制台应用程序调用这些方法时,一切都很好,而且如果我在 Windows 服务中本地托管在我的计算机上时调用 Web 服务,一切也都很好。
只有在服务器上时才会出现此问题 - 我的猜测是当没有人登录到服务器时。
编辑: 找到用户(我认为),结果我得到 "No groups found"。
===========
另一个编辑:我更新了代码,我正在尝试进一步工作。
经过多次实验方法2根本不适合。
方法 2 要求我与要检查的用户一起登录系统以获取他的组。这是无法完成的,因为我没有该用户密码。
我认为其他两种方法(1 和 3)由于网络结构的原因而无效,必须与我的老板讨论。有什么进展我会再更新的
===========
这是我用来获取组的 C# 代码的 link,3 种不同的方法 - none 其中有效。
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class ActiveDirectoryService : System.Web.Services.WebService
{
[WebMethod]
public string GetGroups1(string endUsername)
{
string result;
try
{
var list = new List<string>();
var domain = ConfigurationManager.AppSettings["Domain"];
var serviceUsername = ConfigurationManager.AppSettings["Username"];
var password = ConfigurationManager.AppSettings["Password"];
var context = new PrincipalContext(ContextType.Domain, domain, serviceUsername, password);
var userPrincipal = UserPrincipal.FindByIdentity(context, endUsername);
if (userPrincipal == null)
{
return "Failed to find user: " + endUsername;
}
var authorizationGroups = userPrincipal.GetAuthorizationGroups();
WriteToLogDebug("GetGroups1.authorizationGroups.Count: " + authorizationGroups.Count());
foreach (var current in authorizationGroups)
{
if (current is GroupPrincipal)
{
var groupPrincipal = current as GroupPrincipal;
var groupPrincipalName = groupPrincipal?.Name;
if (!string.IsNullOrWhiteSpace(groupPrincipalName))
{
list.Add(groupPrincipalName);
}
}
}
if (!list.Any())
{
result = "No groups found for user " + endUsername;
}
else
{
result = string.Join(" & ", list);
}
}
catch (Exception ex)
{
result = "Failed to get groups for user " + endUsername + ": " + ex.Message;
WriteToLogException("GetGroups1." + ex.Message);
}
return result;
}
[WebMethod]
public string GetGroups2(string endUsername)
{
string result;
var serviceUsername = ConfigurationManager.AppSettings["Username"];
try
{
var list = new List<string>();
IntPtr token = GetLogonUserToken();
if (token == default(IntPtr))
{
return "Failed to logon user: " + serviceUsername;
}
var windowsIdentity = new WindowsIdentity(token);
WriteToLogDebug("GetGroups2.windowsIdentity.Groups.Count: " + windowsIdentity.Groups.Count());
foreach (var current in windowsIdentity.Groups)
{
try
{
list.Add(current.Translate(typeof(NTAccount)).ToString());
}
catch (Exception ex)
{
WriteToLogException("GetGroups2." + ex.Message);
}
}
if (!list.Any())
{
result = "No groups found for user " + serviceUsername;
}
else
{
result = string.Join(" & ", list);
}
}
catch (Exception ex)
{
result = "Failed to get groups for user " + serviceUsername + ": " + ex.Message;
WriteToLogException("GetGroups2." + ex.Message);
}
return result;
}
[WebMethod]
public string GetGroups3(string endUsername)
{
var result = "No groups found";
try
{
var directoryEntry = GetDirectoryEntry();
if (directoryEntry == null)
{
result = "DirectoryEntry returned null";
}
else
{
var list = new List<string>();
var directorySearcher = new DirectorySearcher(directoryEntry)
{
Filter = "(&(sAMAccountName=" + endUsername + "))"
};
if (directorySearcher == null)
{
WriteToLogDebug("GetGroups3.(directorySearcher == null): " + (directorySearcher == null));
return "Failed to initiate directorySearcher";
}
SearchResultCollection searchResultCollection = null;
try
{
searchResultCollection = directorySearcher.FindAll();
if (searchResultCollection == null)
{
WriteToLogDebug("GetGroups3.(searchResultCollection == null): " + (searchResultCollection == null));
return "Failed to find user: " + endUsername;
}
}
catch (Exception ex)
{
WriteToLogException("GetGroups3.Failed: " + ex.Message);
return "Failed to find user " + endUsername + ": " + ex.Message;
}
if (searchResultCollection.Count == 0)
{
result = "No groups found for user " + endUsername;
}
else
{
WriteToLogDebug("GetGroups3.searchResultCollection.Count: " + searchResultCollection.Count);
foreach (var current in searchResultCollection)
{
var searchResult = current as SearchResult;
foreach (var group in searchResult?.Properties["memberOf"])
{
if (group != null)
list.Add(group.ToString());
}
}
result = string.Join(" & ", list);
}
}
}
catch (Exception ex)
{
result = "Failed to get groups for user " + endUsername + ": " + ex.Message;
WriteToLogException("GetGroups3.Failed: " + ex.Message);
}
return result;
}
private IntPtr GetLogonUserToken()
{
try
{
var LOGON32_LOGON_INTERACTIVE = 2;
//var LOGON32_LOGON_NETWORK = 3;
//var LOGON32_LOGON_BATCH = 4;
//var LOGON32_LOGON_SERVICE = 5;
//var LOGON32_LOGON_UNLOCK = 7;
//var LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
//var LOGON32_LOGON_NEW_CREDENTIALS = 9;
var LOGON32_PROVIDER_DEFAULT = 0;
var domain = ConfigurationManager.AppSettings["Domain"];
WriteToLogDebug("GetLogonUserToken.domain: " + domain);
var serviceUsername = ConfigurationManager.AppSettings["Username"];
WriteToLogDebug("GetLogonUserToken.serviceUsername: " + serviceUsername);
var password = ConfigurationManager.AppSettings["Password"];
WriteToLogDebug("GetLogonUserToken.password: " + password);
LogonUser(serviceUsername, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out IntPtr token);
return token;
}
catch (Exception ex)
{
WriteToLogException("GetLogonUserToken.Failed" + ex.Message);
}
return default(IntPtr);
}
private DirectoryEntry GetDirectoryEntry()
{
DirectoryEntry result;
try
{
var domain = ConfigurationManager.AppSettings["Domain"];
WriteToLogDebug("GetDirectoryEntry.domain: " + domain);
var serviceUsername = ConfigurationManager.AppSettings["Username"];
WriteToLogDebug("GetDirectoryEntry.serviceUsername: " + serviceUsername);
var password = ConfigurationManager.AppSettings["Password"];
WriteToLogDebug("GetDirectoryEntry.password: " + password);
result = new DirectoryEntry
{
Username = serviceUsername,
Password = password,
Path = "LDAP://" + domain
};
}
catch (Exception ex)
{
result = null;
WriteToLogException("GetDirectoryEntry.Failed: " + ex.Message);
}
return result;
}
关于如何从 windows 服务托管的 Web 服务获取用户组的任何建议?
谢谢
最后它确实是一个网络块,在更改使用的域后我设法获得了最终用户和他们的组。
谢谢大家的帮助。
我有一个在服务器上存储文档的 Web 应用程序。在某些情况下,我需要为每个用户组设置某些权限,因为它们存储在 Active Directory 中。
我在服务器上的 Windows 服务中设置了托管的 Web 服务,服务器正在与该 Web 服务联系以获取数据。
当我从常规控制台应用程序调用这些方法时,一切都很好,而且如果我在 Windows 服务中本地托管在我的计算机上时调用 Web 服务,一切也都很好。
只有在服务器上时才会出现此问题 - 我的猜测是当没有人登录到服务器时。
编辑: 找到用户(我认为),结果我得到 "No groups found"。
===========
另一个编辑:我更新了代码,我正在尝试进一步工作。
经过多次实验方法2根本不适合。 方法 2 要求我与要检查的用户一起登录系统以获取他的组。这是无法完成的,因为我没有该用户密码。
我认为其他两种方法(1 和 3)由于网络结构的原因而无效,必须与我的老板讨论。有什么进展我会再更新的
===========
这是我用来获取组的 C# 代码的 link,3 种不同的方法 - none 其中有效。
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class ActiveDirectoryService : System.Web.Services.WebService
{
[WebMethod]
public string GetGroups1(string endUsername)
{
string result;
try
{
var list = new List<string>();
var domain = ConfigurationManager.AppSettings["Domain"];
var serviceUsername = ConfigurationManager.AppSettings["Username"];
var password = ConfigurationManager.AppSettings["Password"];
var context = new PrincipalContext(ContextType.Domain, domain, serviceUsername, password);
var userPrincipal = UserPrincipal.FindByIdentity(context, endUsername);
if (userPrincipal == null)
{
return "Failed to find user: " + endUsername;
}
var authorizationGroups = userPrincipal.GetAuthorizationGroups();
WriteToLogDebug("GetGroups1.authorizationGroups.Count: " + authorizationGroups.Count());
foreach (var current in authorizationGroups)
{
if (current is GroupPrincipal)
{
var groupPrincipal = current as GroupPrincipal;
var groupPrincipalName = groupPrincipal?.Name;
if (!string.IsNullOrWhiteSpace(groupPrincipalName))
{
list.Add(groupPrincipalName);
}
}
}
if (!list.Any())
{
result = "No groups found for user " + endUsername;
}
else
{
result = string.Join(" & ", list);
}
}
catch (Exception ex)
{
result = "Failed to get groups for user " + endUsername + ": " + ex.Message;
WriteToLogException("GetGroups1." + ex.Message);
}
return result;
}
[WebMethod]
public string GetGroups2(string endUsername)
{
string result;
var serviceUsername = ConfigurationManager.AppSettings["Username"];
try
{
var list = new List<string>();
IntPtr token = GetLogonUserToken();
if (token == default(IntPtr))
{
return "Failed to logon user: " + serviceUsername;
}
var windowsIdentity = new WindowsIdentity(token);
WriteToLogDebug("GetGroups2.windowsIdentity.Groups.Count: " + windowsIdentity.Groups.Count());
foreach (var current in windowsIdentity.Groups)
{
try
{
list.Add(current.Translate(typeof(NTAccount)).ToString());
}
catch (Exception ex)
{
WriteToLogException("GetGroups2." + ex.Message);
}
}
if (!list.Any())
{
result = "No groups found for user " + serviceUsername;
}
else
{
result = string.Join(" & ", list);
}
}
catch (Exception ex)
{
result = "Failed to get groups for user " + serviceUsername + ": " + ex.Message;
WriteToLogException("GetGroups2." + ex.Message);
}
return result;
}
[WebMethod]
public string GetGroups3(string endUsername)
{
var result = "No groups found";
try
{
var directoryEntry = GetDirectoryEntry();
if (directoryEntry == null)
{
result = "DirectoryEntry returned null";
}
else
{
var list = new List<string>();
var directorySearcher = new DirectorySearcher(directoryEntry)
{
Filter = "(&(sAMAccountName=" + endUsername + "))"
};
if (directorySearcher == null)
{
WriteToLogDebug("GetGroups3.(directorySearcher == null): " + (directorySearcher == null));
return "Failed to initiate directorySearcher";
}
SearchResultCollection searchResultCollection = null;
try
{
searchResultCollection = directorySearcher.FindAll();
if (searchResultCollection == null)
{
WriteToLogDebug("GetGroups3.(searchResultCollection == null): " + (searchResultCollection == null));
return "Failed to find user: " + endUsername;
}
}
catch (Exception ex)
{
WriteToLogException("GetGroups3.Failed: " + ex.Message);
return "Failed to find user " + endUsername + ": " + ex.Message;
}
if (searchResultCollection.Count == 0)
{
result = "No groups found for user " + endUsername;
}
else
{
WriteToLogDebug("GetGroups3.searchResultCollection.Count: " + searchResultCollection.Count);
foreach (var current in searchResultCollection)
{
var searchResult = current as SearchResult;
foreach (var group in searchResult?.Properties["memberOf"])
{
if (group != null)
list.Add(group.ToString());
}
}
result = string.Join(" & ", list);
}
}
}
catch (Exception ex)
{
result = "Failed to get groups for user " + endUsername + ": " + ex.Message;
WriteToLogException("GetGroups3.Failed: " + ex.Message);
}
return result;
}
private IntPtr GetLogonUserToken()
{
try
{
var LOGON32_LOGON_INTERACTIVE = 2;
//var LOGON32_LOGON_NETWORK = 3;
//var LOGON32_LOGON_BATCH = 4;
//var LOGON32_LOGON_SERVICE = 5;
//var LOGON32_LOGON_UNLOCK = 7;
//var LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
//var LOGON32_LOGON_NEW_CREDENTIALS = 9;
var LOGON32_PROVIDER_DEFAULT = 0;
var domain = ConfigurationManager.AppSettings["Domain"];
WriteToLogDebug("GetLogonUserToken.domain: " + domain);
var serviceUsername = ConfigurationManager.AppSettings["Username"];
WriteToLogDebug("GetLogonUserToken.serviceUsername: " + serviceUsername);
var password = ConfigurationManager.AppSettings["Password"];
WriteToLogDebug("GetLogonUserToken.password: " + password);
LogonUser(serviceUsername, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out IntPtr token);
return token;
}
catch (Exception ex)
{
WriteToLogException("GetLogonUserToken.Failed" + ex.Message);
}
return default(IntPtr);
}
private DirectoryEntry GetDirectoryEntry()
{
DirectoryEntry result;
try
{
var domain = ConfigurationManager.AppSettings["Domain"];
WriteToLogDebug("GetDirectoryEntry.domain: " + domain);
var serviceUsername = ConfigurationManager.AppSettings["Username"];
WriteToLogDebug("GetDirectoryEntry.serviceUsername: " + serviceUsername);
var password = ConfigurationManager.AppSettings["Password"];
WriteToLogDebug("GetDirectoryEntry.password: " + password);
result = new DirectoryEntry
{
Username = serviceUsername,
Password = password,
Path = "LDAP://" + domain
};
}
catch (Exception ex)
{
result = null;
WriteToLogException("GetDirectoryEntry.Failed: " + ex.Message);
}
return result;
}
关于如何从 windows 服务托管的 Web 服务获取用户组的任何建议?
谢谢
最后它确实是一个网络块,在更改使用的域后我设法获得了最终用户和他们的组。 谢谢大家的帮助。