Je reçois une erreur d'un site Web sur lequel j'utilise l'authentification Windows.
Des choses étranges:
Voici ce que je reçois dans un courrier de connexion:
Source: System.DirectoryServices
Message: Le serveur n'est pas opérationnel.
Trace:
à System.DirectoryServices.DirectoryEntry.Bind (Boolean throwIfFail)
sur System.DirectoryServices.DirectoryEntry.Bind ()
sur System.DirectoryServices.DirectoryEntry.get_AdsObject ()
à System.DirectoryServices.DirectorySearcher.FindAll (Boolean findMoreThanOne)
sur System.DirectoryServices.DirectorySearcher.FindOne ()
at Smarthouse.Labs.DataAccess.UserListManager.SaveUser (String windowsUserName)
Voici comment j'implémente DirectorySearch:
private void SaveUser(string windowsUserName)
{
string[] domainAndUser = windowsUserName.Split('\\');
string domain = domainAndUser[0];
string username = domainAndUser[1];
DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain);
DirectorySearcher search = new DirectorySearcher(entry);
try
{
// Bind to the native AdsObject to force authentication.
search.Filter = "(SAMAccountName=" + username + ")";
search.PropertiesToLoad.Add("cn");
search.PropertiesToLoad.Add("sn");
search.PropertiesToLoad.Add("givenName");
search.PropertiesToLoad.Add("mail");
SearchResult result = search.FindOne();
if (result == null)
{
throw new Exception("No results found in Windows authentication.");
}
User userToSave = new User();
userToSave.FirstName = (String) result.Properties["givenName"][0];
userToSave.LastName = (String) result.Properties["sn"][0];
userToSave.Email = (String) result.Properties["mail"][0];
userToSave.Username = windowsUserName;
userToSave.Guid = Guid.NewGuid();
SaveUser(userToSave);
}
catch (Exception ex)
{
throw new Exception("Error authenticating user. " + ex.Message, ex);
}
finally
{
//Dispose service and search to prevent leek in memory
entry.Dispose();
search.Dispose();
}
}
Si d'autres exemples de code sont nécessaires, dites-le moi simplement.
Votre problème est que vous utilisez un nom de domaine "ordinaire" pour la liaison - cela ne fonctionnera pas dans LDAP. En fait, si vous essayez de vous lier à LDAP://MyDomain
, ce que vous êtes vraiment essayez de lier au server appelé MyDomain
.
Vous avez besoin d'une chaîne de liaison LDAP valide - quelque chose comme LDAP://dc=yourdomain,dc=local
ou quelque chose.
Pour connaître votre contexte de liaison LDAP par défaut, utilisez l'extrait de code suivant:
DirectoryEntry deRoot = new DirectoryEntry("LDAP://RootDSE");
if (deRoot != null)
{
string defaultNamingContext = deRoot.Properties["defaultNamingContext"].Value.ToString();
}
Une fois que vous avez cette chaîne, utilisez-la comme chaîne de liaison à votre serveur LDAP.
Et si vous êtes sur .NET 3.5 et supérieur, vous devriez vérifier l'espace de noms System.DirectoryServices.AccountManagement
(S.DS.AM). Lisez tout a propos de ça ici:
Fondamentalement, vous pouvez définir un contexte de domaine et rechercher facilement des utilisateurs et/ou des groupes dans AD:
// set up domain context -- no domain name needed, uses default domain
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);
if(user != null)
{
// do something here....
}
Le nouveau S.DS.AM simplifie vraiment les discussions avec les utilisateurs et les groupes dans AD!
Pour ajouter à la réponse de marc_s ci-dessus , je devais effectuer une recherche dans plusieurs domaines. Donc, pour chaque domaine, j’ai fait ce qui suit:
DirectoryEntry deRoot = new DirectoryEntry("LDAP://" +"DomainName"+ "/RootDSE");
string defaultNamingContext = "LDAP://" + deRoot.Properties["defaultNamingContext"].Value.ToString();
DirectoryEntry mySearchRoot = new DirectoryEntry(defaultNamingContext);
DirectorySearcher myDirectorySearcher = new DirectorySearcher(mySearchRoot);
Une erreur similaire m'est survenue (bien que cela se produise tout le temps et non dans des cas spécifiques, comme indiqué ici) en raison d'une mauvaise chaîne de connexion Active Directory. J'ai utilisé le corp au lieu de la prod 1. Utilisez quelque chose qui fonctionne pour une autre application de votre organisation, le cas échéant.
Vous pouvez utiliser des chaînes de liaison au format LDAP: //mydomain.com: 389. Je continuais à obtenir "Accès refusé" lorsque j'essayais d'utiliser le format LDAP: // DC = mydomain, DC = com. Une fois que je suis passé au format LDAP: //mydomain.com: 389 et lié à l'aide de l'indicateur AuthenticationTypes.ServerBind lors de la construction de mon DirectoryEntry, cela a très bien fonctionné. C'était dans Azure App Service.