简体   繁体   English

IIS在多域林中使用ASP.NET应用的Windows身份验证问题

[英]Windows Authentication issue in IIS using ASP.NET app in a multi-domain forest

I am trying to implement a web-based intranet project that uses Windows Authentication. 我正在尝试实现一个使用Windows身份验证的基于Web的Intranet项目。 The web server (Windows 2012 Server) is in Domain A, but I need to be able to access the site from computers in any domain within the forest. Web服务器(Windows 2012 Server)位于域A中,但我需要能够从林中任何域中的计算机访问该站点。 I am just testing this using computers in domains A and B. 我只是使用域A和B中的计算机对此进行测试。

In IIS 7.0, I have enabled Windows Authentication and disabled all others, including Anonymous Authentication. 在IIS 7.0中,我启用了Windows身份验证,并禁用了所有其他身份验证,包括匿名身份验证。 In web.config I have: 在web.config中,我有:

<authentication mode="Windows"></authentication>
<identity impersonate="true" />
<authorization>
  <deny users="?" />
</authorization>

Authenticated users need to be in AD group "TestGroup"; 经过身份验证的用户必须位于AD组“ TestGroup”中; I removed the <allow groups="TestGroup" /> in web.config for testing purposes; 我出于测试目的在web.config中删除了<allow groups =“ TestGroup” />; I also added a few labels on home page to display my user's ID, groups I belongs to, all members of "TestGroup" and whether I am a member of "TestGroup" or not, jut for debugging purposes. 我还在主页上添加了一些标签来显示我的用户ID,我所属的组,“ TestGroup”的所有成员以及是否是“ TestGroup”的成员(出于调试目的)。

I believe I have done everything correct so far. 我相信到目前为止我所做的一切都正确。 With web.config as is: 使用web.config如下:

  • When I access from a PC in domain A, I am not prompted to log in (whihc is correct since I am already logged in to domain A), and all lebles show correct data. 当我从域A中的PC访问时,系统不会提示我登录(由于我已经登录域A,这是正确的),并且所有提示都显示正确的数据。
  • When I access from a PC in domain B, I am asked to log in (correctly), user ID label shows my ID correctly but shows no groups for my user ID and no group members in "TestGroup". 当我从域B中的PC访问时,系统要求我(正确)登录,用户ID标签正确显示了我的ID,但没有显示用户ID的组,也没有显示“ TestGroup”中的组成员。

If I remove the identity section in web.config: 如果我在web.config中删除了身份部分:

  • When access from a PC in either domain A or domain B, User ID label shows "NT AUTHORITY/NETWORK SERVICE", nothing listed as groups I belong to (since I am now apparently "NT Authority"), but group members for "TestGroup" are listed correctly. 当从域A或域B中的PC访问时,用户ID标签显示“ NT AUTHORITY / NETWORK SERVICE”,没有列出任何属于我的组(因为我现在显然是“ NT Authority”),但是属于“ TestGroup”的组成员”正确列出。 Accessing from PC in domain B pops up login dialog box, correctly. 从域B中的PC访问会正确弹出登录对话框。

If I remove the authorization section and leave identity section in web.config: 如果删除授权部分并将身份部分保留在web.config中:

  • I am not asked to login from PCs in either domain; 不要求我从任一域中的PC登录;
  • Accessing from PC in domain A shows everything correctly 从域A中的PC访问可以正确显示所有内容
  • Accessing from PC in domain B, shows user ID corrctly but no group membership and no users listed for "TestGroup" group. 从域B中的PC访问时,正确显示用户ID,但没有组成员身份,也没有列出“ TestGroup”组的用户。

It seems that in order to be able to show correct user ID, I need to have impersonate set to true; 似乎为了能够显示正确的用户ID,我需要将模拟设置为true。 in order to require users to log in form a PC outside domain AI need to have authorization part, but both together don't seem to work from PCs outside domain A. 为了要求用户从域AI之外的PC登录,AI需要具有授权部分,但两者似乎都无法在域A之外的PC上正常工作。

This is what I am using to get user ID, user group membership and group members: 这是我用来获取用户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;
}

I also tried to use this to see if user is a member of the group but it throws error if I access the site from PC in domain B: 我还尝试使用它来查看用户是否是该组的成员,但是如果我从域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; 
    }
}

What ended up solving my problem was wrapping the functionality in the methods in: 解决我问题的最终方法是将功能包装在以下方法中:

using (System.Web.Hosting.HostingEnvironment.Impersonate())
{
}

For example, I change the method in my original post from: 例如,我将原始帖子中的方法从:

public static StringCollection GetGroupMembers(DomainType eDomainType, string strGroup)
{
    DirectoryEntry de = new DirectoryEntry(adDSADPath);
    System.Collections.Specialized.StringCollection GroupMembers = new System.Collections.Specialized.StringCollection();
...
}

to: 至:

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();
        ...
    }
}

Hope this saves someone else some grief as it caused me a lot! 希望这可以使别人免于悲痛,因为这引起了我很多!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 基于IIS服务器Windows域的ASP.NET MVC 5身份验证 - ASP.NET MVC 5 Authentication based on IIS server's Windows domain 面对IIS和Windows身份验证中托管的ASP.NET的问题 - Facing problem with ASP.NET hosted in IIS and Windows Authentication Asp.net WCF和集成的Windows身份验证和IIS 6.0 - Asp.net WCF and integrated Windows authentication and IIS 6.0 Windows 身份验证不适用于具有 ASP.NET 核心的 IIS - Windows Authentication Does not work on IIS with ASP.NET Core 自定义模块中的iis asp.net Windows身份验证 - iis asp.net windows authentication in a custom module 在 Windows 身份验证的 ASP.Net 5 中使用 IIS Express/Kestrel 时,User.IsInRole 始终为 false - User.IsInRole is always false when using IIS Express / Kestrel in ASP.Net 5 with Windows Authentication 为不在域中的用户测试Windows身份验证的ASP.NET应用程序 - Test ASP.NET application for Windows Authentication for user which is not in domain 在Windows身份验证中使用asp.net中的角色 - using roles in asp.net with windows authentication 将特定域的ASP.NET模拟用户添加到Windows身份验证 - Adding ASP.NET impersonation users of specific domain to windows authentication 在ASP.NET中使用Windows身份验证 - Using Windows Authentication in ASP.NET
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM