mardi 8 janvier 2008

Thread with ASP.NET and Integrated security

Recently, we decided to move to integrated security on all our Dev machines so that we won't need complex security management on the dev db.
Therefore, we used the "impersonate" tag in the web/machine .config as following :
<system.web>
<identity impersonate="true" userName="domain\user" password="password" />

Everything was fine except for the process that created thread for launching parallel DB actions.

Ex of Non working code :

threads.Add(new Thread(new ThreadStart(this.LaunchOneSqlCommand)));



The method "LaunchOneSqlCommand" pops one SQLCommand from the stack of commands to execute and launch them with integrated security specified in the connection string :

public void LaunchOneSqlCommand(object windowsIdentity)

{

SqlCommand com = null;

using (SqlConnection con = new SqlConnection(connectionString))

{

try

{

com = popOne();

if (com != null)

con.Open();

while (com != null)

{

com.Connection = con;

int res = com.ExecuteNonQuery();

...

com = popOne();

}

con.Close();

}

catch (Exception ex)

{
...

throw new MultiThreadedSqlCommandsException(ex.Message);

}

}

...

}



This gave us the terrific error :
Login failed for user ''. The user is not associated with a trusted SQL Server connection.

After some test, we guessed that the thread launched by a Dll under asp.net use the same windowsIdentity as aspnet, and not the one specified with the "impersonate" tag.

Therefore, we had to do some adaptations :

threads.Add(new Thread(new ParameterizedThreadStart(this.LaunchOneSqlCommand)));


And the start must be as following :
for (int i = 0; i < threads.Count; i++)
{
((Thread)thrds[i]).Start(System.Security.Principal.WindowsIdentity.GetCurrent());
}

And the method LaunchOneSqlCommand became

public void LaunchOneSqlCommand(object windowsIdentity)

{

string[] rolesArray = {"role1"};

((WindowsIdentity)windowsIdentity).Impersonate();

Thread.CurrentPrincipal = new System.Security.Principal.GenericPrincipal((IIdentity )windowsIdentity, rolesArray);

...
}