Wednesday, June 21, 2006

Sometimes it is necessary to change the user under whose account asp.net runs to execute a special method. This could be the case e.g. if you want to access an ADS with a local asp.net user and you get an error message "invalid username or password" (there is the possibility to pass a username and passwort, but that didn't work for me).

The usage of the class below is very simple:

...
Impersonation
imp = new Impersonation();
imp.ImpersonateValidUser(
"username", "domain", "password");
//execute your work here
imp.UndoImpersonation();
....




using
System;
using System.Security.Principal;
using System.Runtime.InteropServices;

namespace
Security
{

   public class Impersonation
   
{

      
public const int LOGON32_LOGON_INTERACTIVE = 2;
      
public const int LOGON32_PROVIDER_DEFAULT = 0;
      
WindowsImpersonationContext impersonationContext;

      [DllImport("advapi32.dll")]
      
public static extern int LogonUserA(String lpszUserName, 
         
String lpszDomain,
         
String lpszPassword,
         
int dwLogonType, 
         
int dwLogonProvider,
         
ref IntPtr phToken);
      
      [
DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
      
public static extern int DuplicateToken(IntPtr hToken, 
         
int impersonationLevel, 
         
ref IntPtr hNewToken);

      [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
      
public static extern bool RevertToSelf();

      [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
      
public static extern bool CloseHandle(IntPtr handle);

      public bool ImpersonateValidUser(String userName, String domain, String password)
      {
         
WindowsIdentity tempWindowsIdentity;
         
IntPtr token = IntPtr.Zero;
         
IntPtr tokenDuplicate = IntPtr.Zero;
         
         
if(RevertToSelf())
         {
            
if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 
               LOGON32_PROVIDER_DEFAULT,
ref token) != 0)
            {
               
if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
               {
                  tempWindowsIdentity =
new WindowsIdentity(tokenDuplicate);
                  impersonationContext = tempWindowsIdentity.Impersonate();
                  
if (impersonationContext != null)
                  {
                     CloseHandle(token);
                     CloseHandle(tokenDuplicate);
                     
return true;
                  }
               }
            } 
         }

         if(token!= IntPtr.Zero) CloseHandle(token);
         
if(tokenDuplicate!=IntPtr.Zero) CloseHandle(tokenDuplicate);
         
return false;
      
}

      public void UndoImpersonation()
      {
         impersonationContext.Undo();
      }

   }
}

6/21/2006 8:07:46 AM (Mitteleuropäische Sommerzeit , UTC+02:00)  #    Disclaimer  |  Comments [1]  | 
 Wednesday, May 17, 2006
Anwendungsfall:
  • Es soll nur eine Instanz der Klasse existieren bzw. es soll nicht möglich sein, mehrere Instanzen der Klasse innerhalb eines Anwendungskontexts zu erzeugen.

Beispiele für die Anwendung:

  • Loadbalancer
  • ConnectionPools

Grafische Darstellung:

Beispielcode:

public class Singleton
{

   
private static Singleton instance;

   
private Singleton()
   {
   }

   public static Singleton GetInstance()
   {
      if (Singleton.instance == null)
      {
         Singleton.instance = new Singleton();
      }
      return Singleton.instance;
   }

}

5/17/2006 5:13:25 PM (Mitteleuropäische Sommerzeit , UTC+02:00)  #    Disclaimer  |  Comments [0]  | 

Problem:
You created a WebSite in Visual Studio 2005 and added a reference to another project or a .dll.
Now, if you want to remove this reference, you can't simply delete the .dll in the "Bin" folder of the WebSite. After a rebuild, the deleted .dll will be recreated from VS automatically.

Solution:
To remove the reference, open the Proptery Pages of the WebSite (right click on your WebSite in Solution Explorer and select "Property Pages"). The first time after a restart of VS, you will get the following "dialog":

Just try it once again, and it will work. Here you can remove your reference permanently.

5/17/2006 11:07:33 AM (Mitteleuropäische Sommerzeit , UTC+02:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, May 16, 2006

Search for the file setup.sdb on your cd or dvd.

There, normally on the last line, you will find an entry with the headline "[Product Key]".

This is the case for e.g. Visual Studio Team Foundation Server 2005 or for Visual Studio Team Suite 2005.

5/16/2006 4:04:56 PM (Mitteleuropäische Sommerzeit , UTC+02:00)  #    Disclaimer  |  Comments [1]  | 
 Monday, May 15, 2006
Get all tables including the system ones:
SELECT table_name FROM all_tables;

That will give you only the tables owned by the user that you are connecting as:
SELECT table_name FROM user_tables;

Query table columns:
SELECT * FROM all_tab_cols WHERE table_name = 'whatever table name you are looking for'

Looking for comments on the tables:
SELECT * FROM all_tab_comments WHERE table_name = 'whatever table name you are looking for'
5/15/2006 1:30:39 PM (Mitteleuropäische Sommerzeit , UTC+02:00)  #    Disclaimer  |  Comments [1]  | 
 Tuesday, December 20, 2005

...
Page page = new Page();
Control c = page.LoadControl("YourControl.ascx");
// do Something with your control, DataBind, ...

string html = RenderControl(c);

public static string RenderControl(Control ctrl)
{
   System.Text.
StringBuilder sb = new System.Text.StringBuilder();
   System.IO.
StringWriter tw = new System.IO.StringWriter(sb);
   System.Web.UI.
HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
   ctrl.RenderControl(hw);
   
return sb.ToString();
}

12/20/2005 5:51:20 PM (Mitteleuropäische Zeit , UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, November 30, 2005

You can save your data during a HttpRequest by passing it to System.Web.HttpContext.Current.Items[itemKey].
Objects stored in this Collection will be available during the whole lifecycle of the HttpRequest.

Example of usage:

System.Web.HttpContext.Current.Items["reloadCount"] = 5;

int reloadCount = (int) System.Web.HttpContext.Current.Items["reloadCount"];

11/30/2005 8:44:47 PM (Mitteleuropäische Zeit , UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
 Sunday, October 23, 2005

private DataSet ReadDataSet()
{
   DataSet ds = new DataSet();
   ds.ReadXml(dataPath,
XmlReadMode.ReadSchema);
   return ds;
}

private void WriteDataSet(DataSet ds, string path)
{
   ds.WriteXml(path,
XmlWriteMode.WriteSchema);
}

10/23/2005 10:34:16 AM (Mitteleuropäische Sommerzeit , UTC+02:00)  #    Disclaimer  |  Comments [1]  |