Oct 27, 2007

How to Change the Principal in an ASP.NET Application

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
   // Check whether there is a current user and that
   // authentication has occurred.
   if (!(HttpContext.Current.User == null))
   {
      IIdentity CurrentUserIdentity = HttpContext.Current.User.Identity;
      // Check to see whether the Principal was cached.
      string CachedPrincipalKey = "CachedPrincipal" + id.Name;
      if (HttpContext.Current.Cache[CachedPrincipalKey] == null)
      {
            // Load the principal by calling the GetPrincipal method.
            HttpContext.Current.Cache.Add(
            CachedPrincipalKey,
            GetPrincipal(CurrentUserIdentity),
            null,
            DateTime.MaxValue,
            new TimeSpan(0,30,0),
            CacheItemPriority.Normal,
            null);
      }
      HttpContext.Current.User = (IPrincipal)
      HttpContext.Current.Cache[CachedPrincipalKey];
   }
}


            IF EXISTS (select * from dbo.sysobjects where id = object_id(N'[UserRoles]') and
            OBJECTPROPERTY(id, N'IsUserTable') = 1)
            DROP TABLE [UserRoles]
            GO
            CREATE TABLE [UserRoles] (
            [UserName] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
            [Role] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
            ) ON [PRIMARY]
            GO
            INSERT INTO [Claims].[dbo].[UserRoles]([UserName], [Role])
            VALUES('Chris', 'Admin')
            INSERT INTO [Claims].[dbo].[UserRoles]([UserName], [Role])
            VALUES('Doug', 'Admin')
            INSERT INTO [Claims].[dbo].[UserRoles]([UserName], [Role])
            VALUES('Doug', 'Manager')
            GO

            private IPrincipal GetPrincipal(IIdentity user)
            {
            //Get the roles from the table based on a user name only.
            string SQL =
            "SELECT Role FROM UserRoles WHERE UserName = '" + user.Name + "'";
            SqlConnection MyConnection = new SqlConnection(
            "data source=localhost;initial catalog=Claims;Integrated Security=SSPI");
            SqlCommand MyCommand = new SqlCommand(SQL, MyConnection);
            MyConnection.Open();
            SqlDataReader MyDataReader = MyCommand.ExecuteReader();
            ArrayList alRoles = new ArrayList();
            // Load the roles into an ArrayList.
            while (MyDataReader.Read())
            alRoles.Add(MyDataReader.GetString(0));
            MyDataReader.Close();
            MyCommand.Dispose();
            MyConnection.Close();
            MyConnection.Dispose();
            // Convert the roles to a string[], and load GenericPrincipal.
            string[] myRoles = (string[])al.ToArray(typeof(string));
            return new GenericPrincipal(
            new GenericIdentity(user.Name, user.GetType()),
            myRoles);
            }