Chapter 10



Implementimi i User Profiles, Authentication, dhe Authorization

 

Puna me User Profiles

A user profile in ASP.NET is a set of properties that you define on a per-user basis for your site. This might include color preferences, address information, or other information you wish to track on a per-user basis. Users set up a profile with your site. You store their profile information between site visits. ASP.NET will then automatically load a user’s profile information based on his or her identification. You can then use this profile information in your application to make decisions, prefill data entry boxes, set customizations, and the like.

 

Informacion Baze mbi User Profile

The ASP.NET user profile feature allows you to quickly and easily create a means to define, store, retrieve, and use user profile information in your site. You can configure most of the setup inside of Web.config.

The following list gives the steps involved with setting up user profiles for an ASP.NET Web site:

 

1. Configure a user profile provider this class is used to store and retrieve user profile information to and from a database. There is a default provider for SQL Server. You can also create your own custom profile providers.

 

2. Define the user profile Set up the fields of a user profile you wish to track using the Web.config file. These fields are used by ASP.NET to store data and return it to you in a strongly typed class.

You define a user profile by determining the individual fields you wish to track for each user in your site. For instance, you might want to track the user’s first and last name, the date and time of his or her last visit, preferred font and color settings, and so on. Each value you wish to track is defined as a profile property. Profile properties can be of any type, such as string, DateTime and even custom types you create.

You define user profile fields inside the Web.config fi le by adding a <profile> element to the configuration fi le followed by a <properties> element. Inside the <properties> element, you use the <add> child element to indicate a new field. You name the field using the name attribute. Unless otherwise specified, property fields are of type string. However, you can use the type attribute to specify another specific type.

 

<configuration>

<system.web>

<profile>

<properties>

<add name="FirstName" />

<add name="LastName" />

<add name="LastVisit" type="System.DateTime" />

</properties>

</profile>

</system.web>

</configuration>

 

Anonymous User Profiles: By default, a user profile and its properties are enabled only for authenticated users, those

users you ask to provide login credentials for your site and then authenticate against a user data store. However, you might want to allow anonymous users (those who do not have login credentials to your site) to use features of a user profile. To do so, you start by defining properties as anonymous using the allowAnonymous attribute. You set this attribute value to true for each property for which you want to allow anonymous profiles.

Next, you must add the <anonymousIdentification> element to your Web.config file and set the enabled attribute to true. The <anonymousIdentification> element has several other attributes that you can define to control how cookies are used. However, the default settings are typically sufficient.

<profile>

<properties>

<add name="FirstName" allowAnonymous="true" />

<add name="LastName" allowAnonymous="true" />

<add name="LastVisit" type="System.DateTime" allowAnonymous="true" />

</properties>

</profile>

In this case, anonymous profiles are enabled and ASP.NET creates a unique identification for each user the first time he or she visits your site. This value is stored and tracked with a browser cookie. By default, this cookie is set to expire 70 days after the user last visited your site. If a browser does not support cookies, user profiles can also function without them by storing unique identifiers in the Uniform Resource Locator (URL) of the page request; however, the profile is lost when the user closes his or her browser.

Profile Property Groups: You can group profile properties together under a group name. For example, you might want to define an Address group that contains properties of Street, City, and PostalCode. Adding these items to a group allows you to access them through the profile class in a similar way you would encapsulate data in a class (Profile.Address.Street).

<profile enabled="true">

<properties>

<group name="Address">

<add name="Street" />

<add name="City" />

<add name="PostalCode" />

</group>

</properties>

</profile>

Custom Profile Property Types: You can create your own custom class and use it as a profile property. For example, you might have a class that defines a user’s position in your organization, that user’s reports-to information,

and his or her direct reports. You could use this type as a profile property. To do so, you need to make sure your custom class is marked as serializable using the Serializable attribute. You then reference the custom type using the type attribute of the <add> element.

<profile>

<properties>

<add name="Position" type="MyNamespace.OrgPosition" serializeAs="Binary" />

</properties>

</profile>

 

3. Uniquely identify users You can identify both anonymous and authenticated users of your site. You use a unique value to return their profile from the data storage.

Migrating Anonymous User Profiles:If you enable anonymous user profiles but later wish to allow a user to create authentication credentials, ASP.NET creates a new profile for the user. To avoid losing the user’s anonymous profile information, you respond to the MigrateAnonymous event that ASP.NET raises when a user logs on to your site.

public void Profile_OnMigrateAnonymous(object sender, ProfileMigrateEventArgs args)

{

ProfileCommon anonymousProfile = Profile.GetProfile(args.AnonymousID);

Profile.ZipCode = anonymousProfile.ZipCode;

Profile.CityAndState = anonymousProfile.CityAndState;

Profile.StockSymbols = anonymousProfile.StockSymbols;

//delete the anonymous profile. If the anonymous ID is not

//needed in the rest of the site, remove the anonymous cookie.

ProfileManager.DeleteProfile(args.AnonymousID);

AnonymousIdentificationModule.ClearAnonymousIdentifier();

}

 

4. Set and save a user profile You must provide a means that allows users to set their profile information. This information will then be saved by the configured profile provider.

You can save a user profile by simply setting the values of individual properties and then calling the Profile.Save method. This method will use the configured profile provider to write the profile data out to the configured database.

Typically, you set user profile information in response to a user’s selection, such as his or her preferred color or font size for your Web site. You might also allow users to enter and edit their profile information using a Web form. You do so in a way similar to how you might code any Web form. You add controls to the page, validation, a save button, and an event in your code-behind file to write the data to the data store.

protected void Button1_Click(object sender, EventArgs e)

{

Profile.FirstName = TextBoxFirst.Text;

Profile.LastName = TextBoxLast.Text;

Profile.Save();

}

To set the time of the user’s last visit, you could add code to the Global.asax file. Here you might override the Session_End event.

void Session_End(object sender, EventArgs e)

{

Profile.LastVisit = DateTime.Now;

Profile.Save();

}

 

5. Recognize a returning visitor When a user revisits your site, you can retrieve his or her user profile information as a strongly typed class. Your code can then use the profile information to set customizations, prefill data entry fields, and make other decisions related to the application.

ASP.NET will automatically load a user’s profile based on his or her identification. Again, if you allow anonymous authentication, this identification is passed as a cookie setting. Otherwise, identification happens at the time of authorization. Either way, once the profile is loaded, you can access the data to make decisions such as setting color and font preferences.

In the previous example, a Web form was used to allow a user to set his or her profile information. You could add code to the Load method of this form to initialize the form fields with any profile data.

protected void Page_Load(object sender, EventArgs e)

{

if (!IsPostBack)

{

TextBoxFirst.Text = Profile.FirstName;

TextBoxLast.Text = Profile.LastName;

LabelLastVisit.Text = Profile.LastVisit.ToString();

}

}

 

Shembull:

1. Hap Visual Studio. Krijo website UserProfile.

2. Hap Web.config. Shko tek <system.web>. Tek ky element shto:

<anonymousIdentification enabled="true" />

3. Tek <system.web> shto profilin:

<profile>

<properties>

<add name="Name" allowAnonymous="true" />

<add name="PostalCode" type="System.Int16" allowAnonymous="true" />

<add name="ColorPreference" allowAnonymous="true" />

</properties>

</profile>

4. Shto nje MasterPage.master.

5. Tek MasterPage modifiko body-in:

<body style="font-family: Verdana">

<form id="form1" runat="server">

<asp:Panel ID="Panel1" runat="server">

<h1>My Site</h1>

<hr />

<div style="float: right">

<asp:HyperLink ID="HyperLinkUserProfile" runat="server"

NavigateUrl="UserProfile.aspx"></asp:HyperLink>

</div>

<asp:ContentPlaceHolder id="ContentPlaceHolderMain" runat="server">

</asp:ContentPlaceHolder>

</asp:Panel>

</form>

</body>

6. Modifiko Page_load te MasterPage:

protected void Page_Load(object sender, EventArgs e)

{

if (Profile.Name.Length > 0)

{

HyperLinkUserProfile.Text = "Welcome, " + Profile.Name;

}

else

{

HyperLinkUserProfile.Text = "Set Profile";

}

if (Profile.ColorPreference.Length > 0)

{

Panel1.BackColor =

System.Drawing.Color.FromName(Profile.ColorPreference);

}

}

7. Shto Default.aspx me MasterPage:

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">

<title>Home</title>

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolderMain"

Runat="Server">

<h2>Home</h2>

</asp:Content>

8. Shto UserProfile.aspx si me poshte:

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">

<title>User Profile</title>

</asp:Content>

<asp:Content ID="Content2"

ContentPlaceHolderID="ContentPlaceHolderMain" Runat="Server">

<h2>User Profile</h2>

Name<br />

<asp:TextBox ID="TextBoxName" runat="server"></asp:TextBox>

<br /><br />

Postal Code<br />

<asp:TextBox ID="TextBoxPostal" runat="server"></asp:TextBox>

<br /><br />

Background Preference<br />

<asp:DropDownList ID="DropDownListColors" runat="server">

<asp:ListItem Text="White" Value="White"></asp:ListItem>

<asp:ListItem Text="Yellow" Value="Yellow"></asp:ListItem>

<asp:ListItem Text="Green" Value="Green"></asp:ListItem>

</asp:DropDownList>

<br /><br />

<asp:Button ID="ButtonSave" runat="server" Text="Save" />

</asp:Content>

9. Shto nje event klikimi per buttonin qe therret funksionin ButtonSave_Click

10. Shto funksionin:

        protected void ButtonSave_Click(object sender, EventArgs e)

        {

            Profile.Name = TextBoxName.Text;

            Profile.PostalCode = short.Parse(TextBoxPostal.Text);

            Profile.ColorPreference = DropDownListColors.SelectedValue.ToString();

            Profile.Save();

            Response.Redirect("Default.aspx");

        }

11. Modifiko Page_Load

protected void Page_Load(object sender, EventArgs e)

        {

            if (!IsPostBack)

            {

                TextBoxName.Text = Profile.Name;

                if (Profile.PostalCode > 0)

                {

                    TextBoxPostal.Text = Profile.PostalCode.ToString();

                }

                if (Profile.ColorPreference.Length > 0)

                {

                    DropDownListColors.SelectedValue = Profile.ColorPreference.ToString();

                }

            }

        }

12. Ekzekuto aplikacionin

 

ASP.NET Membership

One key feature of nearly every enterprise Web application is the ability to manage users and their access to the features of a site. This includes creating and editing users, managing their passwords, authenticating users based on role, and much more. In the past, this code was written by nearly every Web application team out there (sometimes more than once).

Each of these controls provides a specific feature required of most user-driven Web sites.

The following is a list of each of these controls and their purpose:

CreateUserWizard This control gathers information from a new user such as user name and password and creates a new user account. You can use the user profile features in conjunction with the CreateUserWizard.

Login This control defines a user interface for prompting users for their user name and password and enables users to select whether they wish to be automatically authenticated the next time they visit your site. You can use the Login control with ASP.NET membership without writing any code, or you can write your own authentication code by adding a handler for the Authenticate event.

LoginView This control is used to display different information if a user is logged into your site. For example, you could use this control to provide links to features that are available only to authenticated users.

LoginStatus You use this control to allow users to link to your login page if they haven’t been authenticated. It displays a link to log out for users who are currently logged in.

LoginName This control displays the current user’s user name (if logged in).

PasswordRecovery This control enables password retrieval or reset for a user by sending an e-mail message or by having the user answer a security question.

ChangePassword This control enables a user who is logged in to change his or her password.

 

Shembuj:

Creating a User Account Creation Page


Creating a Login Page, Adding Password Recovery


Creating a Password Change Page

 


Membership Class

The login controls discussed previously use the methods of the System.Web.Security.Membership class to implement their functionality. This is, for the most part, abstracted from developers. However, there are many cases in which you might want to use these methods yourself. These include creating your own custom user interface outside of the login controls, intercepting login control events, and implementing other security-related code on your site.

In each case, you use the Membership class. It provides capabilities to add, remove, and find users.

CreateUser This method adds a user to the database. Use this method if you create a custom page to enable users or administrators to add new accounts.

DeleteUser This method removes a user from the data store. Use this method if you create custom user management tools.

FindUsersByEmail This method gets a collection of membership users with the specified e-mail addresses.

FindUsersByName This method gets a collection of membership users with the specified user names.

GeneratePassword This method creates a random password of the specified length. Use this if you are implementing custom controls to generate or reset passwords.

GetAllUsers This method returns a collection of all users in the database.

GetNumberOfUsersOnline This method returns the number of users currently logged on.

GetUser This method returns a MembershipUser object representing the current logged-on user. Call this method any time you need to access the current user’s account.

GetUserNameByEmail This method gets a user name with the specified e-mail address.

UpdateUser This method updates the database with the information for the specified user. Use this method if you create a page to enable users or administrators to modify existing accounts.

ValidateUser This method verifies that the supplied user name and password are valid. Use this method to check a user’s credentials if you create your own custom login controls.


Roles Class

AddUserToRole, AddUsersToRole, and AddUsersToRoles These methods add a user to a role.

CreateRole This method creates a new role.

DeleteRole This method deletes an existing role.

FindUsersInRole This method returns a collection of users in a role.

GetAllRoles This method returns a collection of all roles that currently exist.

GetRolesForUser This method returns a collection of roles for the current user.

IsUserInRole This method returns true if the user is a member of a specified role.

RemoveUserFromRole,RemoveUsersFromRole, RemoveUserFromRoles, and RemoveUsersFromRoles These methods remove a user from a role.

 

Shembull 1:

1. Open Visual Studio. Create a new, fi le-based Web site called UserMembership.

2. Create two subfolders in your site. Name one Members and the other Admin. You can do so by right-clicking the project and choosing New Folder.

3. To each subfolder, add a blank ASP.NET Web form named Default.aspx. Later, you’ll access these pages to verify that ASP.NET requires proper authentication.

4. From the Website menu, in Visual Studio, select ASP.NET Confi guration. This should launch the WSAT in a browser.

5. Click the Security tab to get started. In the Users section, click the Select Authentication Type link. On the next screen, select From The Internet and click Done. This enables forms-based authentication.

6. On the Security tab, click the Enable Roles link to enable roles for the site.

7. Next, in the Roles section, click the Create Or Manage Roles link. On the next screen, add a role called Users. Repeat this process to add another role called Administrators.

8. Click the Security tab to return to the main security page. Use the Create User link to add two users. First, create a user named StandardUser. In the Roles section, select the Users role.

Add another user named Admin. In the Roles section, select the Administrators role.

For both users, you can set the password, security question, and e-mail address as you like.

9. Click the Security tab to return to the main security page. In the Access Rules section, click the Create Access Rules link. Create the following rules:

-          Create a rule that denies all anonymous users access to the root of the site.

-          Create a rule that grants all users (outside of anonymous) access to the root of the site.

-          Create a rule that grants users in the Administrators role access to the Admin directory.

-          Create a rule that denies all users access to the Admin directory.

Note that the order of the rule creation is important, as each rule is processed in order. You can move rules up or down in the WSAT interface.

10. Return to Visual Studio. Click the refresh button at the top of Solution Explorer. Notice the inclusion of the ASPNETDB.mdf file in your site. Also notice the additional Web.config file inside the Admin folder. Open both Web.config files for your site and examine the new settings.

 

Shembull 2:

1. Continue working with the Web site you created in the previous exercise. This site is configured to support ASP.NET membership and has users and roles added to the database.

2. Create a new ASP.NET Web form named Login.aspx. Add a Login control to the page.

3. Open the Default.aspx page in the site root. Add the following controls:

-          A LoginStatus control

-          A HyperLink control with the text set to Members only and NavigateUrl set to Members/Default.aspx

-          A HyperLink control with the text set to Administrators only and NavigateUrl set to Admin/Default.aspx

4. Run Default.aspx in a Web browser. Notice that you are redirected to the Login.aspx page. Log in as StandardUser. You should now be able to view the page. Click the Members Only link. You should have full access.

Click the Administrators Only link. You should be redirected to the Login page. Notice that the URL includes a parameter named ReturnUrl that contains the page you were attempting to access.

Log in as Admin and notice you are redirected to the Administrators Only page.

 

Shembull 3:

In this exercise, you update a previously created ASP.NET Web site to disable role manager and use Windows authentication instead.

1. Continue working with the Web site you created in the previous exercise, which has been configured to support ASP.NET membership and has users and roles added to the database.

2. From the Website menu, select ASP.NET Configuration.

3. Click the Security tab. In the Users section, click the Select Authentication Type link. On the next page, select the From A Local Network option. Click Done.

4. In Visual Studio, examine the Web.config file in the Web site root. Notice that the authentication element has been removed, which means forms authentication is no longer enabled. Now remove the <roleManager> element so that the roles element refers to Windows groups instead of the roles you added using Role Manager.

5. In Visual Studio, add a LoginName control to the root Default.aspx page. This enables you to see the user account you are using to access the Web site.

6. Run the site and visit the Default.aspx page. Notice that the LoginName control shows that you are automatically logged in using your Windows user account.

7. Click the Members Only link. If your current account is a member of the local Users group, you are allowed to access the page. Otherwise, ASP.NET denies you access.

8. Click the Administrators Only link. If your current account is a member of the local Administrators group, you are allowed to access the page. Otherwise, ASP.NET denies you access.

Note that in Windows Vista, if you are running the page from Visual Studio, you must also be running Visual Studio as an Administrator.

9. From the Website menu of Visual Studio, select ASP.NET Configuration. Click the Security tab. Notice that you can no longer use the Web Site Administration Tool to manage roles. When Role Manager is disabled, ASP.NET uses Windows groups as roles.

Therefore, you must manage the groups using tools built into Windows, such as the Computer Management console.

10. On the Security tab of the Web Site Administration Tool, click Manage Access Rules. Then, select the Admin subfolder. Notice that it displays the existing rules. Click Add New Access Rule and notice that you can add a rule for specific users, all users, or anonymous users. You cannot, however, add rules to grant access to roles, because

Role Manager has been disabled. To add access rules for Windows Groups using roles, you must manually edit the <authorization> section of the Web.config files.

This exercise worked because the role names you created in Lesson 2 are exactly the same as the default group names in the local Windows user database.

 

Ushtrim Ekstra:

 

Default.aspx

 

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

 

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">

    <title>Home</title>

</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolderMain"

Runat="Server">

 

    <table>

                <tr>

                    <td>

                           <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"

                            DataSourceID="SqlDataSource1" AllowPaging="True"

                                OnRowDataBound="GridView1_RowDataBound" OnRowCommand="GridView1_RowCommand">

                                <Columns>

                                <asp:ButtonField CommandName="ColumnClick" Visible="false" />

                                    <asp:BoundField DataField="OrderID" HeaderText="OrderID" InsertVisible="False"

                                        ReadOnly="True" SortExpression="OrderID" />

                                    <asp:BoundField DataField="CustomerID" HeaderText="CustomerID"

                                        SortExpression="CustomerID" />

                                    <asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID"

                                        SortExpression="EmployeeID" />

                                    <asp:BoundField DataField="ShipName" HeaderText="ShipName"

                                        SortExpression="ShipName" />

                                    <asp:BoundField DataField="ShipCity" HeaderText="ShipCity"

                                        SortExpression="ShipCity" />

                                    <asp:BoundField DataField="ShipRegion" HeaderText="ShipRegion"

                                        SortExpression="ShipRegion" />

                                </Columns>

                            </asp:GridView>

 

                        <asp:SqlDataSource ID="SqlDataSource1" runat="server"

                            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"

                            SelectCommand="SELECT [OrderID], [CustomerID], [EmployeeID], [ShipName], [ShipCity], [ShipRegion] FROM [Orders]">

                        </asp:SqlDataSource>

 

                    </td>

                    <td valign="top">

                        <table>

                            <tr>

                                <td>

                                    <strong>

                                    Selected Row Index:</strong>

                                    <asp:Label ID="lblSelectedRow" runat="server" ForeColor="Red"></asp:Label>

                                </td>

                            </tr>

                             <tr>

                                <td>

                                    <strong>

                                    Selected Column Index:</strong>

                                    <asp:Label ID="lblSelectedColumn" runat="server" ForeColor="Red"></asp:Label>

                                </td>

                            </tr>

                            <tr>

                                <td>

                                    <strong>

                                    Selected Column Title:</strong>

                                    <asp:Label ID="lblSelectedColumnTitle" runat="server" ForeColor="Red"></asp:Label>

                                </td>

                            </tr>

                            <tr>

                                <td>

                                    <strong>

                                    Selected Column Value:</strong>

                                    <asp:Label ID="lblSelectedColumnValue" runat="server" ForeColor="Red"></asp:Label>

                                </td>

                            </tr>

                        </table>

                    </td>

                </tr>

            </table>

        </div>

</asp:Content>

 

Default.aspx.cs

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

 

public partial class _Default : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

 

    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)

    {

        if (e.Row.RowType == DataControlRowType.DataRow)

        {

            if (e.Row.RowType == DataControlRowType.DataRow)

            {

                LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];

                string _jsSingle = ClientScript.GetPostBackClientHyperlink(_singleClickButton, "");

                // Add events to each editable cell

                for (int columnIndex = 0; columnIndex < e.Row.Cells.Count; columnIndex++)

                {

                    // Add the column index as the event argument parameter

                    string js = _jsSingle.Insert(_jsSingle.Length - 2, columnIndex.ToString());

                    // Add this javascript to the onclick Attribute of the cell

                    e.Row.Cells[columnIndex].Attributes["onclick"] = js;

                    // Add a cursor style to the cells

                    e.Row.Cells[columnIndex].Attributes["style"] += "cursor:pointer;cursor:hand;";

                }

            }

        }

    }

 

    protected override void Render(HtmlTextWriter writer)

    {

        foreach (GridViewRow r in GridView1.Rows)

        {

            if (r.RowType == DataControlRowType.DataRow)

            {

                for (int columnIndex = 0; columnIndex < r.Cells.Count; columnIndex++)

                {

                    Page.ClientScript.RegisterForEventValidation(r.UniqueID + "$ctl00", columnIndex.ToString());

                }

            }

        }

        base.Render(writer);

    }

 

    protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)

    {

        if (e.CommandName.ToString() == "ColumnClick")

        {

            foreach (GridViewRow r in GridView1.Rows)

            {

                if (r.RowType == DataControlRowType.DataRow)

                {

                    for (int columnIndex = 0; columnIndex < r.Cells.Count; columnIndex++)

                    {

                        r.Cells[columnIndex].Attributes["style"] += "background-color:White;";

                    }

                }

            }

            int selectedRowIndex = Convert.ToInt32(e.CommandArgument.ToString());

            int selectedColumnIndex = Convert.ToInt32(Request.Form["__EVENTARGUMENT"].ToString());

            GridView1.Rows[selectedRowIndex].Cells[selectedColumnIndex].Attributes["style"] += "background-color:Red;";

            lblSelectedColumn.Text = selectedColumnIndex.ToString();

            lblSelectedRow.Text = selectedRowIndex.ToString();

            lblSelectedColumnTitle.Text = GridView1.Columns[selectedColumnIndex].HeaderText;

            lblSelectedColumnValue.Text = GridView1.Rows[selectedRowIndex].Cells[selectedColumnIndex].Text;

        }

    }

}