Friday, September 9, 2011

Forms Authentication with roles in ASP.NET with C#

Create a New Project
Create a new project, you can use Visual Web Developer or Visual studio to do that and
create folder structure like below.
Solution Structure

Note that I have Admin folder create, secure and easy to differentiate access based on user roles. 
Admin folder in my case will request access to those whose role is "Admin" and "User". Folder 
user will request access only to those whose role is "user" insurance binder and have access to all 
authenticated users At least, no matter what role they have. Each folder has a file. Aspx page that 
displays welcome message, as shown in the first image above.

Creating settings for Web.Config file

Add authentication option following in the web.config file in <system.web>.

  <authentication Mode = "Forms">
        <form DefaultUrl = "default.aspx" loginUrl = "~ / login.aspx" "true"
                                                    
slidingExpiration ="" timeout = "20">
          </ forms>
          </authentication>

For each user to protect a specific folder, you can place fit for them, either in the parent web.config 
file (root folder) or the web.config file in the folder.

Specifying paper settings for the folder in the root web.config file (in this case to the Administration)

<location path ="Admin">
    <system.web>
      <authorization>
        <allow roles = "admin" />
        <deny users="*" />
      </authorization>
    </system.web>
  </location>

Enter this code outside <configuration> <system.web> but under the label of the root web.config file. 
Here I am specifying that if the path contains the name of the administrator folder and only users with 
"admin" roles are allowed and all other users are denied.

Specifying paper settings for the folder in the web.config file specific folder (in this case the user)

<System.web>

    <authorization>

        <allow Roles = "usuario" />

        <deny Users= "*" />

    </ Authorization>

</ System.web>

Enter this code in web.config file folder user. You can specify settings for the user in the root web.config 
file also how I've done for the previous administration. This is just another way of specifying the 
configuration. This configuration should be placed on the label <configuration>.

Specify settings for the authenticated user

<System.web>

    <authorization>

        <Deny Users = "?" />

    </ Authorization>

</ System.web>

Type the following code in the web.config secure folder. This is the specification that all users are denied 
anonymous this folder and only authenticated users can, regardless of their functions.
User Authentication

Assuming you have gone through my previous article mentioned, you have a login page. Now when the user 
clicks the Login button fires Authenticate method allows the code from that method.

private void get()
        {
            string userName = loginControl.UserName;
            string password = loginControl.Password;
            bool rememberUserName = loginControl.RememberMeSet;
            // for this demo purpose, I am storing user details into xml file
            string dataPath = Server.MapPath("~/App_Data/UserInformation.xml");
            DataSet dSet = new DataSet();
            dSet.ReadXml(dataPath);
            DataRow[] rows = dSet.Tables[0].Select(String.Format(" UserName = '{0}' AND Password = 
                                    '{1}'", userName, password));
            // record validated
            if (rows.Length > 0)
            {
                // get the role now
                string roles = rows[0]["Roles"].ToString();
                // Create forms authentication ticket
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                    1, // Ticket version
                    userName, // Username to be associated with this ticket
                    DateTime.Now, // Date/time ticket was issued
                    DateTime.Now.AddMinutes(50), // Date and time the cookie will expire
                    rememberUserName, // if user has chcked rememebr me then create persistent cookie
                    roles, // store the user data, in this case roles of the user
                    FormsAuthentication.FormsCookiePath); // Cookie path specified in the web.config 
                                                     //file in <Forms> tag if any.
                                                 // To give more security it is suggested to hash it
                string hashCookies = FormsAuthentication.Encrypt(ticket);
                HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashCookies); 
                                                             // Hashed ticket
                // Add the cookie to the response, user browser
                Response.Cookies.Add(cookie);
                // Get the requested page from the url
                string returnUrl = Request.QueryString["ReturnUrl"];
                // check if it exists, if not then redirect to default page
                if (returnUrl == null) returnUrl = "~/Default.aspx";
                Response.Redirect(returnUrl);
            }
            else // wrong username and password
            {
                // do nothing, Login control will automatically show the failure message
                // if you are not using Login control, show the failure message explicitely
            }
 
        }

In the above method, I used the UserInformation.xml file that contains the credentials and role information to the
user.
I Reding xml file and get all the users credentials in the data set and using the method of DataTable.Select, I'm
filtering based on user registration and password. If you find a record, then I'm adding the entry into
FormsAuthentication cookie encrypt and then redirected to the requested URL in your otherwise the default page.
Note that I have not used standard method FormsAuthentication.RedirectFromLoginPage FormsAuthenticate
method to redirect the login page after authentication of users, not to establish the role of users in the cookie and
I will not be able to validate users based on the paper. To add functions to users in the authentication ticket, I used
the FormsAuthenticationTicket class and pass the required data as parameter (Note that the roles are passed as
constructor parameter FormsAuthenticationTicket UserData).

So far we have set the forms authentication ticket with the required data, including user roles in the cookie, now
how to retrive the information about each request and that a request comes from the paper type? So we must use the
event Global.asx Application_AuthenticateRequest file. See the code below.

Application_AuthenticateRequest protected void (object sender, EventArgs e)

{

    / / Check if the safety information that exists for this request

    if (HttpContext. Current.User! = null)
    {
        / / Check if the user is authenticated, any authenticated cookie (ticket) which exists to this user
        if (HttpContext. Current.User.Identity.IsAuthenticated)
        {
            / / Check if authentication is done by FormsAuthentication
            if (HttpContext. Current.User.Identity is FormsIdentity)
            {
                / / Get roles for this application stored entry
                / / Get the user's identity
                FormsIdentity identity =(FormsIdentity) HttpContext.Current.User.Identity;
                / / Get the ticket authetication ways for the user
                Ticket FormsAuthenticationTicket = identity.Ticket;

                / / Get the roles stored in the entry as UserData

                String [] roles = ticket.UserData.Split ('');

                / / Create generic principal and assign it to the current request

                HttpContext. Current.User = new System.Security.Principal. GenericPrincipal (identity, roles);

            }

        }

    }

}

This even after checking the user exists, he / she is authenticated and the user type is FormsIdentity identy
number, I am getting the actual identity of the user and get the ticket I have put in the time Authentiacting.
Once you have authenticated the note, I just got the UserData of the bill, which was divided for the papers
(remember he had kept the papers as comma separated values). Now we have the current users roles so we
can move to the current user in the GenericPrincipal the current identity and assign this to the user object
curent. This allows us to use the IsInRole method to check whether a user belongs to a particular function
or not.

How to check if the user has a particular role?

To check whether a user belongs to a particulr paper, use the code below. This code returns true if the current
 record is from the user is authenticated and has a role as an administrator.

HttpContext. Current.User.IsInRole ("admin")

How to check if the user is authenticated?

To check whether the user is authenticated or not, use the code below.

HttpContext. Current.User.Identity.IsAuthenticated

For authenticated user name

HttpContext. Current.User.Identity.Name

If you've followed the steps, you should try runnig application. Try logging in as administrator you can access all pages (Admin, User, insurance, home). Try to login as a user and the user can access, home insurance, but not management. Try logging in as safe and you will be able to access a secure home, but the non-administrator. Try to visit all the links and you can access links Home only.



1 comment :

  1. there should be an image of the output :) or sample output

    ReplyDelete