Validate user in a trusted domain using DirectoryServices

 

In previous post, we talk about using Active Directory membership provider in a trusted domain scenario. Using an Active Directory membership provider should be necessary to configure connection string and provider for each domain. There could be situation you prefer not to configure connection string and provider. You may try to use DirectoryServices in such scenario.

Environment

==================

Domain1: lab.com - forest root domain

DC account: lab\Administrator (ADDC2008R2)

Web server account: lab\webserver (Application host server)

User account: lab\backend

Domain2: yinshi.net - forest root domain

DC account: yinshi\Administrator (AD2DC2008R2)

User account: yinshi\yinshiweb

Note: The trust relationship is a two-way forest trust in my test and only root domain in the forest. The situation may be different for the different trust situation.

Access to application from different trusted domain

====================

I created a simple test web application using DirectoryServices. The application is hosted in a web server in Domain1 (lab.com).

Note: In both scenarios, you need to locate the correct forest or domain so that you can continue validating the user.

Scenario 1:

We provide domain\username as UserName and Password in the Login page.

clip_image001 clip_image002

And then try to validate the user from the entry domain using code below:

string[] partsOfname = UserName.Text.Split("\\".ToCharArray());

//Get the domain name, username and password

strdomain = partsOfname[0];

strUsername = partsOfname[1];

strPassword = Password.Text;

bool authenticated = false;

//Initializes a new instance of the DirectoryEntry class that binds this instance to the node in Active Directory Domain Services located at entered domain.

//Use the given username and password to try to retrieve the NativeObject property from this DirectoryEntry class instance.

using (DirectoryEntry oDEfind = new DirectoryEntry(@"LDAP://" + strdomain, strUsername, strPassword))

{

try

{

//If you get the object without having a thrown exception, this means that the AD was able to authenticate the user.

object obj = oDEfind.NativeObject;

authenticated = true;

msg.Text = authenticated.ToString();

}

catch (Exception ex)

{

//strdomain, strUsername or strPassword invalid

msg.Text = ex.Message;

}

}

The results:

clip_image003clip_image004

Scenario 2:

I have also tried to retrieve user using UserName and Password in the Login page. But in this attempt, I haven’t take a duplicate username in all trusted domains into account. And to search in all trusted forest may influence the application performance and the risk of exception.

clip_image005

1. Try to get the user from current forest.

//Not consider the duplicate credentials

strUsername = UserName.Text;

strPassword = Password.Text;

bool authenticated = false;

//get current forest

Forest currentforest = Forest.GetCurrentForest();

//search in current forest first

DirectoryEntry oDEcurrent = new DirectoryEntry("LDAP://" + currentforest.Name);

DirectorySearcher search = new DirectorySearcher(oDEcurrent);

search.Filter = "(SAMAccountName=" + strUsername + ")";

search.ReferralChasing = ReferralChasingOption.All;

SearchResult res = search.FindOne();

if (res != null)

{

//Create new instance in current forest and validate user with credential

oDEcurrent = new DirectoryEntry("LDAP://" + currentforest.Name, strUsername, strPassword, AuthenticationTypes.Secure);

try

{

object obj = oDEcurrent.NativeObject;

authenticated = true;

msg.Text = authenticated.ToString();

}

catch (Exception exp)

{

msg.Text = exp.Message;

}

}

2. If no user found, get forest trust information from the current forest and search in trusted forests.

//get trust target forest name

foreach (ForestTrustRelationshipInformation trust1 in currentforest.GetAllTrustRelationships())

{

string trustforest = trust1.TargetName;

DirectoryEntry oDEtrust = new DirectoryEntry("LDAP://" + trustforest);

search = new DirectorySearcher(oDEtrust);

search.Filter = "(SAMAccountName=" + strUsername + ")";

search.ReferralChasing = ReferralChasingOption.All;

res = search.FindOne();

if (res != null)

{

oDEtrust = new DirectoryEntry("LDAP://" + trustforest, strUsername, strPassword, AuthenticationTypes.Secure);

try

{

object obj = oDEtrust.NativeObject;

authenticated = true;

msg.Text = authenticated.ToString();

//if get the user, exit for

break;

}

catch (Exception exp)

{

msg.Text = exp.Message;

}

}

else

{

msg.Text = "No user";

}

}

clip_image006

Reference

======================

Introduction to System.DirectoryServices.ActiveDirectory (S.DS.AD)

https://msdn.microsoft.com/en-us/library/bb267453.aspx

Example26. Get forest trust information from the current forest

https://msdn.microsoft.com/en-us/library/bb267453.aspx#sdsadintro_topic3_managetrusts

DirectoryEntry Class

https://msdn.microsoft.com/en-us/library/System.DirectoryServices.DirectoryEntry(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectory.directorycontext(v=vs.110).aspx

Best Regards

Yingjie Shi from APAC DSI Team