Hello
I posted a thread about this a while back, but I can't actually find it
again so I can reply to it with the solution I found, so I'm making a new
thread and hoping it goes to the top of the Google search results for the
error like the previous thread.
This is actually a solution to a problem, not a call for help, so you can
stop reading now unless you're actually interested in the solution :)
Problem:
When connecting to Active Directory using a DirectoryEntry object, and
passing username and password credentials, returns an error when binding.
(Binding occurs once you try to execute something, such as a search, or
access connection properties). The error message is "The authentication
mechanism is unknown".
Example code:
// Bind to Active Directory using LDAP Protocol
DirectoryEntry entry = new DirectoryEntry("LDAP://DOMAIN", "myusername",
"mypassword", AuthenticationTypes.Secure);
System.DirectoryServices.PropertyCollection props = entry.Properties;
foreach(string propName in props.PropertyNames)
{
Console.WriteLine( "{0} = {1}", propName, props[propName] );
}
Diagnosis:
In general, this code will work and you'll get a list of the AD LDAP
properties. However, you might get the "The authentication mechanism is
unknown" error. When I searched for help on this error everywhere I could
find, nobody could supply a solution, or even an explanation of what was
happening.
What I have found is that it is almost certainly a problem with security
permissions. More specifically, if you are running under a system account
rather than an account that belongs to the domain you're connecting to. And
mostly, you will probably only get this problem when you're running ASP.NET.
To help you test what account may be causing problems for you, add this line
of code before you do any DirectoryEntry operations:
Console.WriteLine("Current Identity = {0}, IsSystem={1},
IsAuthenticated={2}, AuthenticationType={3}, Token={4}", identity.Name,
identity.IsSystem, identity.IsAuthenticated, identity.AuthenticationType,
identity.Token.ToString() );
When the problem occurred for me, I got this output:
Current Identity = NT AUTHORITY\SYSTEM, IsSystem=True, IsAuthenticated=True,
AuthenticationType=NTLM, Token=10228
If you're getting this, check your machine.config located in
%SYSTEMROOT%\Microsoft.NET\Framework\vx.x.xxxx\CON FIG e.g.
c:\windows\Microsoft.NET\Framework\v1.0.3705\CONFI G for 1.0 Framework on
Windows XP. Search for the <processModel section. Have a look at userName
attribute; it will be set to "system" most probably. This runs ASP.NET under
a privileged local system account and is actually a big security hole; this
was the default setting in Beta 2 but was changed to "machine" later on.
When set to machine, ASP.NET will then run under the MACHINENAME\ASPNET
account which should actually make your code work!
In theory, the code should work anyway, because you're specifying the
credentials you are binding to the directory with. I suspect it will be
something to do with initial tokens passed when binding, from some of the
packet sniffing I was doing trying to find what happens when you bind.
Solutions:
The solution is to run your ASP.NET application under an account that can
access AD. There are a couple of ways to do this:
1) You can actually do all your work WITHOUT sending a username and password
to the DirectoryEntry bind if you're running under the system account. This
isn't an anonymous bind, it's a privileged one, because you can actually
search the whole AD tree (an anonymous bind to AD gives you almost nothing
to look at)
e.g. DirectoryEntry entry = new DirectoryEntry("LDAP://DOMAIN");
This isn't an option for me, as I need to bind with the username and
password as a form of authentication.
2) Ensure ASP.NET runs under the MACHINENAME\ASPNET account by setting the
userName attribute in the processModel section of machine.config to
"machine" (make sure the password attribute is set to "AutoGenerate"). This
will enforce the change on all ASP.NET apps. This is recommended as using
"system" is insecure and essentially "deprecated".
3) Run your specific web application under a specified username and
password, such as a domain login. Do this by adding the following line to
web.config:
<identity impersonate="true" userName="DOMAIN\myusername"
password="mypassword"/>
</system.web>
</configuration>
Troubleshooting:
1) First you should test that you can actually get to the Active Directory
using the LDAP method by using a standard LDAP client such as LDAPBrowser
2) You should make sure the username / password you're using can actually
bind to the AD using the LDAP Browser
3) Use the line of code a bit further up to troubleshoot what account your
app is running under (i.e. to see whether your impersonation or
machine.config changes have taken effect)
I hope this helps you! Was a frustrating error that had no documentation or
solutions I could find.
Cheers
David Moore <davidATrealdevelopments.com>