Authentication with Active Directory from Forms Authentication

Español

There are two ways that .Net can use to do Active Directory Authentication and this are:

To make a “bind” to Active Directory using LDAP.
To use the Win32 Logon API.

If .Net 3.5 is available you can authenticate with this method:

private bool ValidateExternalUser(string username, string password)
{
    using(PrincipalContext context = new PrincipalContext(ContextType.Domain, _defaultDomain))
    {
          return context.ValidateCredentials(username, password, ContextOptions.Negociate);
    }
}

Before .Net 3.5 you can just bind with your own object:

public bool AuthenticateActiveDirectory(string Domain, string UserName, string Password)
{
    try
    {
          DirectoryEntry entry = new DirectoryEntry(”LDAP://” + Domain, UserName, Password);
          object nativeObject = entry.NativeObject;
        return true;
    }
    catch (DirectoryServicesCOMException) { return false; }
}

Using Win32 Logon API:

It’s very large and fortunately already documented here:
http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html

Another method that we can use when the authentication has to consider Active Directory or SAM local accounts is the following:

[SecurityCritical, DirectoryServicesPermission(SecurityAction.Assert, Unrestricted=true)]
public bool Validate(string userName, string password, ContextOptions connectionMethod)
{
    if ((userName != null) && (userName.Length == 0))
    {
        return false;
    }
    if ((this.contextType == ContextType.Domain) || (this.contextType == ContextType.ApplicationDirectory))
    {
        try
        {
            NetworkCredential creds = new NetworkCredential(userName, password);
            this.BindLdap(creds, connectionMethod);
            return true;
        }
        catch (LdapException exception)
        {
            if (exception.ErrorCode != ExceptionHelper.ERROR_LOGON_FAILURE)
            {
                throw;
            }
            return false;
        }
    }
    return this.BindSam(this.serverName, userName, password);
}

Final Conclusions:

The Win32 Logon API method may be is more verbose of all but has more capabilities like inform the reason behind a failed authentication like account expiration, or if the password has not been set, etc. If you don’t need this advanced behavior it’s recommended the 3.5 or just bind approach.

References:

http://stackoverflow.com/questions/290548/c-validate-a-username-and-password-against-active-directory
http://stackoverflow.com/questions/30861/authenticating-domain-users-with-system-directoryservices
http://archive.devx.com/security/articles/ps0602/ps0602-4.asp
http://support.microsoft.com/kb/316748/en-us
http://msdn.microsoft.com/en-us/library/ms180890(VS.80).aspx
http://www.adventuresindevelopment.com/2009/06/02/how-to-authenticate-a-user-in-active-directory-using-aspnet/
http://support.microsoft.com/kb/180548/en-us
http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html

Advertisements

3 thoughts on “Authentication with Active Directory from Forms Authentication

  1. I think that a pragmatic approach is most of the times better than a complex one. I know that when you are starting a project, security stuff is not always the key area of your project, at least when you are still coding on prototypes, on those stages basic authentication capabilities could be enough. Some times you never need the level of detail that the Win32 LogOn API can give you.

    Two cuestions for you:

    1) Any recommendation on when the Win32 Logon API is really needed?

    2) Do you know any implementation of a .NET real wrapper for that API?

    • Thanks for your comment, I will think that security if is not key area it’s an important one. But also it’s a common one, and it’s better as you said to leverage that to your framework or infrastucture.

      Thinking about your questions:

      1) I don’t particularly love too much regulatory and compliance stuff, but in my own experience there are implementations where you have to comply with things like block accounts when some user give wrong passwords at least three times. Another example could be an application heavily used that have capabilities like establish your password for the first time or to get notifications when you have to change your password and you don’t have direct contact with a windows domain (like members of your team that work a lot on the field away of your corporate infrastructure).

      2) No, but I know about partial .Net wrappers used to solve real business requirements. I think that the developers of this implementations where as just as pragmatic as you said so, and choose just wrap the essential.

      And last but not least, the better aproach will be no code at all! (Windows Authentication, not Forms)

  2. Pingback: Autenticación con Active Directory y Forms Authentication « Ernesto Ocampo Blog en Español

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s