我正在尝试实现一个使用Windows身份验证的基于web的intranet项目。web服务器(Windows 2012 Server)位于域A中,但我需要能够从林中任何域中的计算机访问该站点。我只是使用域A和B中的计算机来测试它。
在IIS 7.0中,我启用了Windows身份验证并禁用了所有其他身份验证,包括匿名身份验证。在web.config中,我有:
<authentication mode="Windows"></authentication>
<identity impersonate="true" />
<authorization>
<deny users="?" />
</authorization>
经过身份验证的用户需要在AD组"TestGroup“中;出于测试目的,我删除了web.config中的;我还在主页上添加了一些标签,以显示我的用户ID、我所属的组、"TestGroup”的所有成员以及我是否是“TestGroup”的成员。
我相信到目前为止我做的每件事都是正确的。按原样使用web.config:
如果我删除web.config中的identity部分:
如果我在web.config中删除了authorization部分,而保留了identity部分:
似乎为了能够显示正确的用户ID,我需要将impersonate设置为true;为了要求用户从域A之外的PC登录,我需要具有授权部分,但这两者似乎不能从域A之外的PC一起工作。
这是我用来获取用户ID、用户组成员和组成员的方法:
WindowsIdentity wiUser = WindowsIdentity.GetCurrent();
string sID = wiUser.Name.ToUpper().Repl("DomainA\\", string.Empty);
string sGroupName = @"TestGroup";
List<string> lsGroups = Utils.GetUserADGroups(sID);
bool bTC = lsGroups.Contains(sGroupName);
StringCollection scGroupMembers = Utils.GetGroupMembers(Utils.DomainType., sGroupName);
static string adDomain = "USA.ABC.DEF.COM";
static string adContainer = "DC=USA,DC=abc,DC=def,DC=com";
static string adADPath = "LDAP://USA.abc.def.com";
public static List<string> GetUserADGroups(string UserName)
{
List<string> lsGroups = new List<string>();
try
{
PrincipalContext pc = new PrincipalContext(ContextType.Domain, adDomain, adContainer);
UserPrincipal up = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, UserName);
PrincipalSearchResult<Principal> psr = up.GetGroups(pc);
foreach (Principal p in psr)
{
lsGroups.Add(p.Name);
}
}
catch (Exception)
{
}
return lsGroups;
}
public static StringCollection GetGroupMembers(DomainType eDomainType, string strGroup)
{
DirectoryEntry de = new DirectoryEntry(adDSADPath);
System.Collections.Specialized.StringCollection GroupMembers = new System.Collections.Specialized.StringCollection();
try
{
//DirectoryEntry DirectoryRoot = new DirectoryEntry(sADPath);
DirectorySearcher DirectorySearch = new DirectorySearcher(de, ("(CN=" + (strGroup + ")")));
SearchResultCollection DirectorySearchCollection = DirectorySearch.FindAll();
foreach (SearchResult DirectorySearchResult in DirectorySearchCollection)
{
ResultPropertyCollection ResultPropertyCollection = DirectorySearchResult.Properties;
foreach (string GroupMemberDN in ResultPropertyCollection["member"])
{
DirectoryEntry DirectoryMember = new DirectoryEntry(("LDAP://" + GroupMemberDN));
System.DirectoryServices.PropertyCollection DirectoryMemberProperties = DirectoryMember.Properties;
object DirectoryItem = DirectoryMemberProperties["sAMAccountName"].Value;
if (null != DirectoryItem)
{
GroupMembers.Add(DirectoryItem.ToString());
}
}
}
}
catch (Exception ex)
{
}
return GroupMembers;
}
我还尝试使用它来查看用户是否是组的成员,但如果我从域B中的PC访问该站点,则会抛出错误:
public static bool IsMember(string UserName, string GroupName)
{
try
{
PrincipalContext pc = new PrincipalContext(ContextType.Domain, adDomain, adContainer);
UserPrincipal up = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, UserName);
PrincipalSearchResult<Principal> psr = up.GetGroups(pc);
foreach (Principal result in psr)
{
if (string.Compare(result.Name, GroupName, true) == 0)
return true;
}
return false;
}
catch (Exception e)
{
throw e;
}
}
发布于 2016-12-12 23:12:58
最终解决我的问题的是将方法中的功能包装在:
using (System.Web.Hosting.HostingEnvironment.Impersonate())
{
}
例如,我将原始帖子中的方法从:
public static StringCollection GetGroupMembers(DomainType eDomainType, string strGroup)
{
DirectoryEntry de = new DirectoryEntry(adDSADPath);
System.Collections.Specialized.StringCollection GroupMembers = new System.Collections.Specialized.StringCollection();
...
}
至:
public static StringCollection GetGroupMembers(DomainType eDomainType, string strGroup)
{
using (System.Web.Hosting.HostingEnvironment.Impersonate())
{
DirectoryEntry de = new DirectoryEntry(adDSADPath);
System.Collections.Specialized.StringCollection GroupMembers = new System.Collections.Specialized.StringCollection();
...
}
}
希望这能为其他人节省一些痛苦,因为它给我带来了很多麻烦!
https://stackoverflow.com/questions/41084274
复制相似问题