Saturday, January 31, 2009

Membership, Roles and Profile -Part 2

Introduction

In Part 1 we learnt about customizing the CreateUserWizard control, adding the newly registered user to a default role and storing data in Profile properties. Going further this article will explain how to develop an administrative page that manages User-Role mapping. We will also discuss Login controls such as Login and LoginView.

Managing User-Role mapping

Once a user registers with the web site, the administrator needs to manage his roles. The administrator can certainly use the "Web Site Administration Tool" for this purpose. However, in many real world applications this facility is provided within the application itself. This makes sense because the person handling the user-role mapping may not always have access to VS.NET 2005.

We will now develop a web form that allows an administrator to manage user-role mapping. The web form looks as shown in Figure 1.

Figure 1

At the top there is a ListBox that displays list of all the registered users of the web site. Just below the ListBox there is a CheckBoxList that displays list of the roles in the systen. Once you select a user his current roles are displayed in the CheckBoxList. The administrator can add/remove user from one or more roles. Once the desired roles are assigned the administrator needs to click on the "Assign Roles" button to save the changes.

Developing the web form

Begin by adding a new web form called RoleManager.aspx in the web site. Design the web form as shown in Figure 1. Make sure to set the AutoPostBack property of ListBox to true.

In the Page_Load event we will populate the ListBox with list of all the users and the CheckBoxList with list of roles. Write the following code in the Page_Load event handler.

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MembershipUserCollection users = Membership.GetAllUsers();
foreach (MembershipUser user in users)
{
ListBox1.Items.Add(user.UserName);
}

string[] allRoles = Roles.GetAllRoles();
foreach (string role in allRoles)
{
CheckBoxList1.Items.Add(role);
}
}
}

The GetAllUsers() method of Membership object returns a list of all the users in the form of a collection called MembershipUserCollection. Each element in this collection is of type MembershipUser. We iterate through the collection and add the UserName of each user to the ListBox.

On the same lines the GetAllRoles() method of Roles object returns a list of all roles in the form of string array. We iterate through this array and add all the roles to the CheckBoxList.

Once a user s selected in the ListBox his current roles need to be selected in the CheckBoxList. This is done by handling SelectedIndexChanged event of the ListBox as shown below:

protected void ListBox1_SelectedIndexChanged
(object sender, EventArgs e)
{
string[] userRoles = Roles.GetRolesForUser
(ListBox1.SelectedValue);
foreach (string role in userRoles)
{
ListItem li = CheckBoxList1.Items.FindByValue(role);
if (li != null)
{
li.Selected = true;
}
}
}

We used GetRolesForUser() method of Roles object and pass the selected user from the ListBox. The method returns all the roles that the user belongs to in the form of a string array. We then iterate through the array and mark the corresponding item from the CheckBoxList as selected.

Finally, when the administrator adds or removes the user to one or more roles the changes need to be saved. This is done by handling Click event of the "Assign Roles" button as shown below:

protected void Button1_Click(object sender,
EventArgs e)
{
foreach (ListItem li in CheckBoxList1.Items)
{
if (li.Selected == true)
{
if (Roles.IsUserInRole(ListBox1.SelectedValue,
li.Value) == false)
{
Roles.AddUserToRole(ListBox1.SelectedValue, li.Value);
}
}
else
{
if (Roles.IsUserInRole(ListBox1.SelectedValue,
li.Value))
{
Roles.RemoveUserFromRole(ListBox1.SelectedValue,
li.Value);
}
}
}
}

We iterate through the CheckBoxList to check which roles are to be assigned to the user. The user is added to a role using AddUserToRole() method of the Roles object. Similarly, a user is removed from a role by using RemoveUserFromRole() method of the Roles object. Note that trying to add a user to a role to which he already belongs to will result in an exception and hence we used IsUserInRole() check.

Using Login control

Now that we have developed the role management page we will move further to develop the Login page. Recollect that we developed Login.aspx in Part 1 but it provides just registration facility. We will modify the same web form to include login functionality also.

Open the web form in VS.NET and drag and drop a Login control on it. The Login control has many properties that allow you to customize its appearance and behavior. We will use only few of them in our example. Set DisplayRememberMe property to false. This property governs whether to display "Remember Me" checkbox or no. Also, set DestinationPageUrl property to "Default.aspx". This property controls the web form that is displayed to the user upon successful login.

Figure 2 shows the Login.aspx after incorporating Login control. Note that the Login control internally takes care to validate the user against the database and issue a FormsAuthentication cookie. If you wish you can do the same thing yourself by creating a custom login user interface and then using Membership.ValidateUser() and FormsAuthentication.SetAuthCookie() methods.

Figure 2

Using LoginName, LoginStatus and LoginView controls

Once the user is logged in we take him to Default.aspx. We want to develop Default.aspx as shown in Figure 3.

Figure 3

We display a welcome message for the user followed by Logout LinkButton. Depending on the role of the user we display a Label mentioning his role. Finally, we display the Profile information that we captured during registration.

In order to develop this page, open Default.aspx in VS.NET. Drag and drop a Label and set its Text property to Welcome. Drag and drop a LoginName control beside it. The LoginName control automatically display the User ID of the current user. You can do the same think yourself using User.Identity.Name property. Also, drag and drop a LoginStatus control beside the LoginName control that you just put. The LoginStatus control displays the current state (Logged in or Logged out) of the user and allows the user to Login or Log out depending on the current status. You can achieve this yourself by using a LinkButton and calling FormsAuthentication.SignOut() method in its Click event.

Now comes the interesting part. As per our functionality we need to display a Label (or any piece of UI in general) specific to the role of the user. This is often called as Role Based Security. As you might have guessed there are two ways to accomplish our task. In the "do it yourself" way you can use Roles.IsUserInRole() method to check the role of the user and then set the Label accordingly. However, the LoginView control makes your life easy. It is declarative way to hide/show certain part of the UI to the user depending on their role.

In order to use the LoginView control, drag and drop it on the web form. From the smart tag select "Edit RoleGroups..." (Figure 4).

Figure 4

This will open "RoleGroup Collection Editor" as shown in Figure 5.

Figure 5

Using this editor you can add one or more Role Groups. A role group is a set of roles that can have a UI template in the LoginView control. In our example we created three role groups of each role in the system but you can have multiple roles per group also.

Once you add the role groups you will notice various "Views" in the smart tag (Figure 6). Each view is nothing but a UI template which is displayed if the user belongs to the role group.

Figure 6

Select each view and drag and drop a Label in it. Set the Text property of the Label to indicate the role name.

The control also has anononymous and LoggedIn templates which are meant for displaying UI for anonymous and authenticated users (no role checking).

Finally, add the following code in the Page_Load event handler.

protected void Page_Load(object sender, EventArgs e)
{
Label10.Text = Profile.FullName;
Label11.Text = Profile.DOB.ToShortDateString();
Label12.Text = Profile.Salary.ToString();
Label13.Text = Profile.Address.Street + ",\r\n" +
Profile.Address.State + ",\r\n" +
Profile.Address.Country + " - " +
Profile.Address.PinCode;
}

Here, we simply show the Profile property values in Labels. Note that these details were captured during registration process.

That's it! You are now ready to test the application complete with registration, profile, authentication and role based security.

Note : this article is collected from the website all right reserved BinaryIntellect Consulting.

No comments: