2016-12-11 4 views
0

J'essaie de mettre en œuvre un projet intranet Web qui utilise l'authentification Windows. Le serveur Web (Windows 2012 Server) se trouve dans le domaine A, mais je dois pouvoir accéder au site à partir d'ordinateurs de n'importe quel domaine de la forêt. Je suis juste en train de tester cela en utilisant des ordinateurs dans les domaines A et B. Dans IIS 7.0. J'ai activé Windows Authntication et désactivé tous les autres, y compris l'authentification anonyme. En web.config je:Problème d'authentification Windows dans IIS à l'aide de l'application asp.net dans la forêt multi-domaine

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

Les utilisateurs authentifiés doivent être dans le groupe AD "TestGroup"; J'ai supprimé le < allow groups = "TestGroup"/> dans web.config à des fins de test; J'ai également ajouté quelques étiquettes sur la page d'accueil pour afficher l'identifiant de mon utilisateur, les groupes auxquels j'appartiens, tous les membres de "TestGroup" et si je suis membre de "TestGroup" ou non, jut à des fins de débogage. Je crois que j'ai tout fait correctement jusqu'à présent. Voici le problème:

Avec web.config comme est:

Quand je l'accès depuis un PC dans le domaine A, je ne suis pas invité à se connecter (whihc est correct puisque je suis déjà connecté au domaine A), et tous les lebles montrent des données correctes. Lorsque j'accède à partir d'un PC dans le domaine B, je suis invité à me connecter (correctement), l'étiquette d'identification affiche correctement mon ID mais ne montre aucun groupe pour mon ID utilisateur et aucun membre du groupe dans "TestGroup".

Si je supprime la section d'identité web.config:

Lorsque l'accès à partir d'un PC dans chaque domaine A ou domaine B, l'étiquette d'identification de l'utilisateur affiche « NT AUTHORITY/NETWORK SERVICE », rien répertorié comme groupes auxquels j'appartiens à (puisque je suis maintenant apparemment "Autorité NT"), mais les membres du groupe "TestGroup" sont listés correctement. L'accès à partir du PC dans le domaine B ouvre la boîte de dialogue de connexion, correctement.

Si je retire la section d'autorisation et laisser la section d'identité web.config:

Je ne suis pas demandé de vous connecter des PC dans les deux domaines; accéder à partir du PC dans le domaine A montre tout correctement Accès à partir du PC dans le domaine B, affiche l'ID utilisateur corrctly mais pas d'appartenance au groupe et aucun utilisateur répertorié pour le groupe "TestGroup".

Il semble que pour être en mesure d'afficher l'ID utilisateur correct, j'ai besoin d'avoir l'identité d'identité définie sur true; Pour obliger les utilisateurs à se connecter à un PC en dehors du domaine A, j'ai besoin d'une partie d'autorisation, mais les deux ne semblent pas fonctionner à partir de PC en dehors du domaine A.

C'est ce que j'utilise pour obtenir l'ID utilisateur, appartenance à un groupe d'utilisateurs et les membres du groupe:

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

J'ai aussi essayé de l'utiliser pour voir si l'utilisateur est un membre du groupe, mais il jette erreur si J'accéder au site à partir du PC dans le domaine 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; 
    } 
} 

Répondre

0

Ce qui a fini par résoudre mon problème enveloppait la fonctionnalité dans les méthodes:

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

Par exemple, je change la méthode dans mon message d'origine à partir de:

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

Hope this sauve quelqu'un d'autre quelque chagrin comme il m'a fait beaucoup!