Main Page | Photo Gallery | Turkish Blog | Delete Language Cookie  RSS 2.0 Atom 1.0 CDF  
Daron Yöndem - Anonymous Personalization Trick in Web Parts
a developers draft...
 Sunday, November 13, 2005

ASP.NET 2.0 provides a Web Parts framework, allowing programmers easily integrate drag’n drop menus etc in their web portals. This framework is easy to use and all client based design settings are stored by ASP.NET data providers in an easy way. The developer has nothing to do with the save or load process of web parts design based settings. This article will not cover how we can use Web Parts. It’s possible to find lots of article around web about Web Parts.

ASP.NET 2.0 Web Parts framework is working with Membership framework as well as with Forms or Windows authentication modes. The problem is that, if you don’t want to use any authentication mode, you can’t use Web Parts. The client user, who will able to change the web sites design with web parts, should be authenticated. If not ASP.NET Web Parts framework can’t save users design settings with data providers and with that reason doesn’t allow even to switch design mode.

The Idea Behind

If we just need that all users connecting to our web site should be authenticated, we need to register all users to our web sites authentication system. We will use Forms Authentication and provide some tricky way. Users will be registered with our site in a hidden way with some cookie. We will recognize our visitors with their cookie and authenticate them automatically to get web parts design options available for them.

Hidden Authentication

First we will set up our web site for Forms Authentication. You just need to modify you Web.Config file as below;

        <!--
            The <authentication> section enables configuration
            of the security authentication mode used by
            ASP.NET to identify an incoming user.
        -->
        <authentication mode="Forms" />

We will provide for each visiter a cookie to recognize users identity to be able to show them their design settings. We need an identity name for each visiter. We will create a random guide number to use as identity.

                Dim MyCookieName As String = "Reminder"
                Dim MyCookie As System.Web.HttpCookie = Request.Cookies(MyCookieName)
                Dim UserID As String
                UserID = System.Guid.NewGuid.ToString.Replace("-", "")
                MyCookie = New System.Web.HttpCookie(MyCookieName, UserID)
                MyCookie.Expires = DateTime.Now.AddYears(10)
                Response.Cookies.Add(MyCookie)

Our cookie name is “Remdiner”. You can change the name for your projects. Our Cookie Data is the random guide name “UserID” that we generated by .NET Frameworks “System.Guid.NewGuid” class. Now we can programmatically recognize our visitor each time they visit our web portal.

We should now authenticate our user with his Guid Name "UserID" to our Forms Authentication system. In normal situation ASP.NET uses cookies to store forms authentication data. We will just simulate that process manually.

                Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, UserID, DateTime.Now, DateTime.Now.AddSeconds(30), False, "roles")
                Dim encryptedTicket As String = FormsAuthentication.Encrypt(authTicket)
                authCookie = New HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
                Response.Cookies.Add(authCookie)

Now our user is authenticated to our web site with forms authentication and can access Web Parts design properties.

We will have lots of visitors designing our web site for themselves and then just never visit again our web site or just delete their cookie and loose their identity as well as their design settings. So why do we need to store all visitors design settings if they even don’t visit our web site since last year? With the code below we connect manually to ASP.NET Membership data store and delete users settings and profile manually, checking the last activity date of user.

            Dim LastDate As Date = Date.Now.AddYears(-1)
           
            Dim cnn As System.Data.SqlClient.SqlConnection = New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("LocalSqlServer").ConnectionString)
            Dim cmd As System.Data.SqlClient.SqlCommand
            cmd = New System.Data.SqlClient.SqlCommand("DELETE FROM aspnet_PersonalizationPerUser where UserID IN (SELECT UserID from aspnet_Users where [LastActivityDate] < @Date)", cnn)
            cmd.Parameters.Add("@Date", Data.SqlDbType.DateTime)
            cmd.Parameters.Item("@Date").Value = LastDate
            Try
                cnn.Open()
                cmd.ExecuteNonQuery()
            Catch ex As Exception
                Response.Write(ex.Message)
            Finally
                cnn.Close()
            End Try
           
            cmd = New System.Data.SqlClient.SqlCommand("DELETE FROM aspnet_Users where [LastActivityDate] < @Date", cnn)
            cmd.Parameters.Add("@Date", Data.SqlDbType.DateTime)
            cmd.Parameters.Item("@Date").Value = LastDate
            Try
                cnn.Open()
                cmd.ExecuteNonQuery()
            Catch ex As Exception
                Response.Write(ex.Message)
            Finally
                cnn.Close()
                cmd.Dispose()
                cnn.Dispose()
            End Try

The complete solution is below;

    Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
                          
        If Page.IsPostBack = False Then
            Dim authCookie As HttpCookie = Request.Cookies(FormsAuthentication.FormsCookieName)
            If authCookie Is Nothing Then
                Dim MyCookieName As String = "Reminder"
                Dim MyCookie As System.Web.HttpCookie = Request.Cookies(MyCookieName)
                Dim UserID As String
                If MyCookie Is Nothing Then
                    UserID = System.Guid.NewGuid.ToString.Replace("-", "")
                    MyCookie = New System.Web.HttpCookie(MyCookieName, UserID)
                    MyCookie.Expires = DateTime.Now.AddYears(10)
                    Response.Cookies.Add(MyCookie)
                Else
                    UserID = MyCookie.Value
                End If
                Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, UserID, DateTime.Now, DateTime.Now.AddSeconds(30), False, "roles")
                Dim encryptedTicket As String = FormsAuthentication.Encrypt(authTicket)
                authCookie = New HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
                Response.Cookies.Add(authCookie)
                Response.Redirect(Request.Url.ToString)
            End If
           
            Dim LastDate As Date = Date.Now.AddYears(-1)
           
            Dim cnn As System.Data.SqlClient.SqlConnection = New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("LocalSqlServer").ConnectionString)
            Dim cmd As System.Data.SqlClient.SqlCommand
        
            cmd = New System.Data.SqlClient.SqlCommand("DELETE FROM aspnet_PersonalizationPerUser where UserID IN (SELECT UserID from aspnet_Users where [LastActivityDate] < @Date)", cnn)
            cmd.Parameters.Add("@Date", Data.SqlDbType.DateTime)
            cmd.Parameters.Item("@Date").Value = LastDate
            Try
                cnn.Open()
                cmd.ExecuteNonQuery()
            Catch ex As Exception
                Response.Write(ex.Message)
            Finally
                cnn.Close()
            End Try
           
            cmd = New System.Data.SqlClient.SqlCommand("DELETE FROM aspnet_Users where [LastActivityDate] < @Date", cnn)
            cmd.Parameters.Add("@Date", Data.SqlDbType.DateTime)
            cmd.Parameters.Item("@Date").Value = LastDate
            Try
                cnn.Open()
                cmd.ExecuteNonQuery()
            Catch ex As Exception
                Response.Write(ex.Message)
            Finally
                cnn.Close()
                cmd.Dispose()
                cnn.Dispose()
            End Try
        End If
    End Sub

The scenario starts with checking the Forms Authentication cookie. If we already authenticated the user, we need nothing to do. If there isn’t Forms Authentication cookie, we check further if we got our identity cookie. If there is an identity cookie “Reminder”, we can load users identity and authenticate it with forms authentication. This way, all users ancient design settings comes automatically to our web portal. If the user doesn’t have our “Reminder” cookie, we create an identity and store it for that user and authenticate it with the new identity to the authentication system.

After having done all this process, we check for ancient users and delete ones, which doesn’t have at least 1 year activity on our web portal.

Conclusion

You just need to use this system on the "Page_Load" event of your web forms where you are using web parts design properties. Have fun using this tricky method on your future portal developments.

Sunday, November 13, 2005 12:48:04 PM (GMT Standard Time, UTC+00:00)  #    Comments [4]   ASP.NET 2.0  | 
Copyright © 2008 Daron Yöndem. All rights reserved.