簡體   English   中英

IIS在多域林中使用ASP.NET應用的Windows身份驗證問題

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

我正在嘗試實現一個使用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中刪除了<allow groups =“ TestGroup” />; 我還在主頁上添加了一些標簽來顯示我的用戶ID,我所屬的組,“ TestGroup”的所有成員以及是否是“ TestGroup”的成員(出於調試目的)。

我相信到目前為止我所做的一切都正確。 使用web.config如下:

  • 當我從域A中的PC訪問時,系統不會提示我登錄(由於我已經登錄域A,這是正確的),並且所有提示都顯示正確的數據。
  • 當我從域B中的PC訪問時,系統要求我(正確)登錄,用戶ID標簽正確顯示了我的ID,但沒有顯示用戶ID的組,也沒有顯示“ TestGroup”中的組成員。

如果我在web.config中刪除了身份部分:

  • 當從域A或域B中的PC訪問時,用戶ID標簽顯示“ NT AUTHORITY / NETWORK SERVICE”,沒有列出任何屬於我的組(因為我現在顯然是“ NT Authority”),但是屬於“ TestGroup”的組成員”正確列出。 從域B中的PC訪問會正確彈出登錄對話框。

如果刪除授權部分並將身份部分保留在web.config中:

  • 不要求我從任一域中的PC登錄;
  • 從域A中的PC訪問可以正確顯示所有內容
  • 從域B中的PC訪問時,正確顯示用戶ID,但沒有組成員身份,也沒有列出“ TestGroup”組的用戶。

似乎為了能夠顯示正確的用戶ID,我需要將模擬設置為true。 為了要求用戶從域AI之外的PC登錄,AI需要具有授權部分,但兩者似乎都無法在域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; 
    }
}

解決我問題的最終方法是將功能包裝在以下方法中:

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

希望這可以使別人免於悲痛,因為這引起了我很多!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM