2016-12-11 25 views
0

Я пытаюсь реализовать проект веб-интрасети, который использует проверку подлинности Windows. Веб-сервер (Windows 2012 Server) находится в домене A, но мне нужно иметь доступ к сайту с компьютеров в любом домене в лесу. Я просто тестирую это, используя компьютеры в доменах A и B. В IIS 7.0. я включил Windows Authntication и отключил все остальные, включая анонимную аутентификацию. В web.config у меня есть:Проблема аутентификации Windows в IIS с использованием приложения asp.net в многодоменном лесу

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

Аутентифицированные пользователи должны быть в AD группы "TestGroup"; Я удалил < allow groups = "TestGroup"/> в web.config для тестирования; Я также добавил несколько ярлыков на главной странице, чтобы отобразить идентификатор пользователя, группы, к которым я принадлежу, всех членов «TestGroup» и является ли я членом «TestGroup» или нет, для целей отладки. Я считаю, что до сих пор все сделано правильно. Вот проблема:

С web.config как:

Когда я получить доступ с компьютера в домене А, я не предлагается войти в систему (whihc правильно, так как я уже вошли в домен A), и все лепестки показывают правильные данные. Когда я получаю доступ с ПК в домене B, меня просят войти (правильно), идентификатор пользователя правильно отображает мой идентификатор, но не показывает группы для моего идентификатора пользователя и членов группы в «TestGroup».

Если удалить раздел идентичности в web.config:

Когда доступ с ПК в любом домене А или домен В, идентификаторе пользователя этикетка показывает «NT AUTHORITY/NETWORK SERVICE», ничего, перечисленный в качестве групп я принадлежу (поскольку теперь я, по-видимому, «авторитет NT»), но члены группы для «TestGroup» перечислены правильно. Доступ с ПК в домене B корректно отображает диалоговое окно входа в систему.

Если удалить раздел авторизации и оставить раздел идентичности в web.config:

Я не просил, чтобы войти в систему с ПК в любой области; Доступ с ПК в домене A показывает все правильно Доступ с ПК в домене B, идентификационный код пользователя, но не членство в группе, и ни один из пользователей, перечисленных для группы «TestGroup».

Похоже, что для того, чтобы показать правильный идентификатор пользователя, мне нужно присвоить значение impersonate true; чтобы пользователи могли входить в систему из-за внешнего домена A. Мне нужно иметь часть авторизации, но обе вместе не работают с ПК вне домена A.

Это то, что я использую, чтобы получить идентификатор пользователя, группы пользователей членства и группы членов:

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:

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; 
    } 
} 

ответ

0

Что в конечном итоге решить мою проблему обмотать функциональность в методах в:

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

Надеется, что это спасает кого-то еще какое-то горе, как это вызвало у меня много!