programming4us
programming4us
SECURITY

Security Fundamentals : Forms Authentication

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
10/10/2010 5:34:37 PM
In old-fashioned ASP programming, developers had to create their own security systems. A common approach was to insert a little snippet of code at the beginning of every secure page. This code would check for the existence of a custom cookie. If the cookie didn't exist, the user would be redirected to a login page, where the cookie would be created after a successful login.

ASP.NET uses the same approach in its forms authentication model. You are still responsible for creating the login page. However, you don't need to create the security cookie manually, or check for it in secure pages, because ASP.NET handles these tasks automatically. You also benefit from ASP.NET's support for sophisticated validation algorithms, which make it all but impossible for users to spoof their own cookies or try other hacking tricks to fool your application into giving them access.

Figure 1 shows a simplified security diagram of the forms authentication model in ASP.NET.

Figure 1. ASP.NET forms authentication

To implement forms-based security, you need to follow three steps:

  1. Set the authentication mode to forms authentication in the web.config file. (If you prefer a graphical tool, you can use the WAT during development or IIS Manager after deployment.)

  2. Restrict anonymous users from a specific page or directory in your application.

  3. Create the login page.

You'll walk through these steps in the following sections.

1. Web.config Settings

You define the type of security in the web.config file by using the <authentication> tag.

The following example configures the application to use forms authentication by using the <authentication> tag. It also sets several of the most important settings using a nested <forms> tag. Namely, it sets the name of the security cookie, the length of time it will be considered valid (in minutes), and the page that allows the user to log in.

<configuration>
<system.web>
<authentication mode="Forms">
<forms name="MyAppCookie"
loginUrl="~/Login.aspx"
protection="All"
timeout="30" path="/" />
</authentication>
...
</system.web>
</configuration>

Table 1 describes these settings. They all supply default values, so you don't need to set them explicitly. For a complete list of supported attributes, consult the Visual Studio Help.

Table 1. Forms Authentication Settings
AttributeDescription
nameThe name of the HTTP cookie to use for authentication (defaults to .ASPXAUTH). If multiple applications are running on the same web server, you should give each application's security cookie a unique name.
loginUrlYour custom login page, where the user is redirected if no valid authentication cookie is found. The default value is Login.aspx.
protectionThe type of encryption and validation used for the security cookie (can be All, None, Encryption, or Validation). Validation ensures the cookie isn't changed during transit, and encryption (typically Triple-DES) is used to encode its contents. The default value is All.
timeoutThe number of idle minutes before the cookie expires. ASP.NET will refresh the cookie every time it receives a request. The default value is 30.
pathThe path for cookies issued by the application. The default value (/) is recommended, because case mismatches can prevent the cookie from being sent with a request.

2. Authorization Rules

If you make these changes to an application's web.config file and request a page, you'll notice that nothing unusual happens, and the web page is served in the normal way. This is because even though you have enabled forms authentication for your application, you have not restricted anonymous users. In other words, you've chosen the system you want to use for authentication, but at the moment none of your pages needs authentication.

To control who can and can't access your website, you need to add access control rules to the <authorization> section of your web.config file. Here's an example that duplicates the default behavior:

<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" />
</authentication>

<authorization>
<allow users="*" />
</authorization>
...
</system.web>
</configuration>

The asterisk (*) is a wildcard character that explicitly permits all users to use the application, even those who haven't been authenticated. But even if you don't include this line in your application's web.config file, this is still the behavior you'll see, because ASP.NET's default settings allow all users. (Technically, this behavior happens because there's an <allow users="*"> rule in the root web.config file. If you're curious, you can find this file a directory like c:\Windows\Microsoft.NET\Framework\[Version]\Config, where [Version] is the version of ASP.NET that's installed, like v4.0.30319.)

To change this behavior, you need to explicitly add a more restrictive rule, as shown here:

<authorization>
<deny users="?" />
</authorization>

The question mark (?) is a wildcard character that matches all anonymous users. By including this rule in your web.config file, you specify that anonymous users are not allowed. Every user must be authenticated, and every user request will require the security cookie. If you request a page in the application directory now, ASP.NET will detect that the request isn't authenticated. It will then redirect the request to the login page that's specified by the loginUrl attribute in the web.config file. (If you try this step right now, the redirection process will cause an error, unless you've already created the login page.)

Now consider what happens if you add more than one rule to the authorization section:

<authorization>
<allow users="*" />
<deny users="?" />
</authorization>

When evaluating rules, ASP.NET scans through the list from top to bottom and then continues with the settings in any .config file inherited from a parent directory, ending with the settings in the base machine.config file. As soon as it finds an applicable rule, it stops its search. Thus, in the previous case, it will determine that the rule <allow users="*"> applies to the current request and will not evaluate the second line. This means these rules will allow all users, including anonymous users.

But consider what happens if these two lines are reversed:

<authorization>
<deny users="?" />
<allow users="*" />
</authorization>

Now these rules will deny anonymous users (by matching the first rule) and allow all other users (by matching the second rule).

2.1. Controlling Access to Specific Directories

A common application design is to place files that require authentication in a separate directory. With ASP.NET configuration files, this approach is easy. Just leave the default <authorization> settings in the normal parent directory, and add a web.config file that specifies stricter settings in the secured directory. This web.config simply needs to deny anonymous users (all other settings and configuration sections can be omitted).

<!-- This web.config file is in a subfolder. -->
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>

NOTE

You cannot change the <authentication> tag settings in the web.config file of a subdirectory in your application. Instead, all the directories in the application must use the same authentication system. However, each directory can have its own authorization rules.

2.2. Controlling Access to Specific Files

Generally, setting file access permissions by directory is the cleanest and easiest approach. However, you also have the option of restricting specific files by adding <location> tags to your web.config file.

The location tags sit outside the main <system.web> tag and are nested directly in the base <configuration> tag, as shown here:

<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" />
</authentication>

<authorization>
<allow users="*" />
</authorization>
...
</system.web>

<location path="SecuredPage.aspx">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>

<location path="AnotherSecuredPage.aspx">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>


</location>
</configuration>

In this example, all files in the application are allowed, except SecuredPage.aspx and AnotherSecuredPage.aspx, which have an additional access rule denying anonymous users. Notice that even when you use multiple <location> sections to supply different sets of authorization rules, you still only include one <authentication> section. That's because a web application can use only one type of authentication.

You can also use the location tags to set rules for a specific subdirectory. It's up to you whether you want to use this approach or you prefer to create separate web.config files for each subdirectory, as described in the previous section.


2.3. Controlling Access for Specific Users

The <allow> and <deny> rules don't need to use the asterisk or question mark wildcards. Instead, they can specifically identify a user name or a list of comma-separated user names. For example, the following list specifically restricts access from three users. These users will not be able to access the pages in this directory. All other authenticated users will be allowed.

<authorization>
<deny users="?" />
<deny users="matthew,sarah" />
<deny users="john" />
<allow users="*" />
</authorization>

You'll notice that the first rule in this example denies all anonymous users. Otherwise, the following rules won't have any effect, because users won't be forced to authenticate themselves.

The following rules explicitly allow two users. All other user requests will be denied access, even if they are authenticated.

<authorization>
<deny users="?" />
<allow users="matthew,sarah" />
<deny users="*" />
</authorization>

Don't confuse these user names with the Windows user account names that are configured on your web server. When you use forms authentication, your application's security model is separate from the Windows user account system. Your application assigns the user name when a user logs in through the login page. Often, you'll choose user names that correspond to IDs in a database. The only requirement is that your user names need to be unique.

3. The WAT

You have another way to set up your authentication and authorization rules. Rather than edit the web.config file by hand, you can use the WAT from inside Visual Studio. The WAT guides you through the process, although you'll find it's still important to understand what changes are actually being made to your web.config file. It's also often quicker to enter a list of authorization rules by hand rather than use the WAT.

To use the WAT for this type of configuration, select Website => ASP.NET Configuration from the menu. Next, click the Security tab. You'll see the window shown in Figure 2, which gives you links to set the authentication type, define authorization rules (using the Access Rules section), and enable role-based security. (Role-based security is an optional higher-level feature you can use with forms authentication. You'll learn more about how it works and how to enable it in the next chapter.)

Figure 2. The Security tab in the WAT

To set an application to use forms authentication, follow these steps:

  1. Click Select Authentication Type.

  2. Choose the From the Internet option.

  3. Click Done. The appropriate <authorization> tag will be created in the web.config file.

The Select Authentication options are worded in a slightly misleading way. It's true that applications that have users connecting from all over the Internet are sure to use forms authentication. However, applications that run on a local network might also use forms authentication—it all depends on how they connect and whether you want to use the information in existing accounts. In other words, a local intranet gives you the option to use Windows authentication but doesn't require it.


Next, it's time to define the authorization rules. To do so, click the Create Access Rules link. (You can also change existing rules by clicking the Manage Access Rules link.) Using the slightly convoluted page shown in Figure 3, you have the ability to create a rule allowing or restricting specific users to the entire site or a specific page or subfolder. For example, the rule in Figure 3 will deny the user jenny from the entire site once you click OK to add it.

Figure 3. Adding an authorization rule

To manage multiple rules, you'll need to click the Manage Access Rules link. Now you'll have the chance to change the order of rules (and hence the priority, as described earlier), as shown in Figure 4. If you have a large number of rules to create, you may find it's easier to edit the web.config file by hand. You might just want to create one initial rule to make sure it's in the right place and then copy and paste your way to success.

Figure 4. Ordering authorization rules

The Security tab is a little overwhelming at first glance because it includes a few features you haven't been introduced to yet. For example, the Security tab also allows you to create and manage user records and roles, as long as you're willing to use the prebuilt database structure that ASP.NET requires. You'll learn more about these details, which are part of a broad feature called membership, in the next chapter. For now, you'll concentrate on the authentication and authorization process.

4. The Login Page

Once you've specified the authentication mode and the authorization rules, you need to build the actual login page, which is an ordinary .aspx page that requests information from the user and decides whether the user should be authenticated.

ASP.NET provides a special FormsAuthentication class in the System.Web.Security namespace, which provides shared methods that help manage the process. Table 2 describes the most important methods of this class.

Table 2. Members of the FormsAuthentication Class
MemberDescription
FormsCookieNameA read-only property that provides the name of the forms authentication cookie.
FormsCookiePathA read-only property that provides the path set for the forms authentication cookie.
Authenticate()Checks a user name and password against a list of accounts that can be entered in the web.config file.
RedirectFromLoginPage()Logs the user into an ASP.NET application by creating the cookie, attaching it to the current response, and redirecting the user to the page originally requested.
SignOut()Logs the user out of the ASP.NET application by removing the current encrypted cookie.
SetAuthCookie()Logs the user into an ASP.NET application by creating and attaching the forms authentication cookie. Unlike the RedirectFromLoginPage() method, it doesn't forward the user back to the initially requested page.
GetRedirectUrl()Provides the URL of the originally requested page. You could use this with SetAuthCookie() to log a user into an application and make a decision in your code whether to redirect to the requested page or use a more suitable default page.
GetAuthCookie()Creates the authentication cookie but doesn't attach it to the current response. You can perform additional cookie customization and then add it manually to the response.
HashPasswordForStoringInConfigFile()Encrypts a string of text using the specified algorithm (SHA1 or MD5). This hashed value provides a secure way to store an encrypted password in a file or database.

A simple login page can put these methods to work with little code. To try it, begin by enabling forms authentication and denying anonymous users in the web.config, as described earlier:

<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" />
</authentication>

<authorization>
<deny users="?" />
<allow users="*" />

</authorization>
...
</system.web>
</configuration>

Now, users will be redirected to a login page named Login.aspx that you need to create. Figure 5 shows an example of the simple login page that you might build.

Figure 5. A typical login page

When the user clicks the Login button, the page checks whether the user has typed in the password Secret and then uses the RedirectFromLoginPage() method to log the user in. Here's the complete page code:

Public Partial Class Login
Inherits System.Web.UI.Page

Protected Sub cmdLogin_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles cmdLogin.Click
If txtPassword.Text.ToLower() = "secret" Then
FormsAuthentication.RedirectFromLoginPage(txtName.Text, False)
Else
lblStatus.Text = "Try again."
End If
End Sub

End Class

The RedirectFromLoginPage() method requires two parameters. The first sets the name of the user. The second is a Boolean variable that specifies whether you want to create a persistent cookie (one that stays on the user's hard drive for a longer period of time). However, in an effort to be more secure, ASP.NET no longer honors this property in the way it was originally designed. (You'll learn more about persistent cookies shortly, in the section named "Persistent Cookies.")

Obviously, the approach used in the login page isn't terribly secure—it simply checks that the user supplies a hard-coded password. In a real application, you'd probably check the user name and password against the information in a database and sign the user in only if the information matches exactly.

You can test this code with the FormsSecurity website that's included with the downloadable code for this chapter. If you request the SecuredPage.aspx file, you'll be redirected to Login.aspx. After entering the correct password, you'll return to SecuredPage.aspx.

4.1. Retrieving the User's Identity

Once the user is logged in, you can retrieve the identity through the built-in User property, as shown here:

Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load

lblMessage.Text = "You have reached the secured page, "
lblMessage.Text &= User.Identity.Name + "."
End Sub

You don't need to place the code in the login page. Instead, you can use the User object to examine the current user's identity any time you need to do so.

Figure 6 shows the result of running this code.

Figure 6. Accessing a secured page

You can access the User object in your code because it's a property of the current Page object. The User object provides information about the currently logged-in user. It's fairly simple—in fact, User provides only one property and one method:

  • The Identity property lets you retrieve the name of the logged-in user and the type of authentication that was used.

  • The IsInRole() method lets you determine whether a user is a member of a given role (and thus should be given certain privileges). You'll use IsInRole() later in this chapter.

UNDERSTANDING IDENTITIES

The User object is standardized so that it can work with any type of authentication system. One consequence of this design is that the User.Identity property returns a different type of object depending on the type of authentication you're using.

For example, when using forms authentication, the identity object is an instance of the FormsIdentity class. When using Windows authentication, you get a WindowsIdentity object instead. And if the user isn't logged in at all, you get a GenericIdentity. (All these classes implement the IIdentity interface, which standardizes them.)

Most of the time, you don't need to worry about this sleight of hand. But occasionally you might want to cast the User.Identity property to the more specific type to get access to an extra piece of information. For example, the FormsIdentity object provides the security ticket (in a property named Ticket), which isn't available through the standard IIdentity interface. This ticket is an instance of the FormsAuthenticationTicket class, and it provides a few miscellaneous details, like the time the user logged in and when the ticket will expire. Similarly, the WindowsIdentity object provides additional information that relates to Windows accounts (such as whether the current user is using a guest account or a system account).


4.2. Signing Out

Any web application that uses forms authentication should also feature a prominent logout button that destroys the forms authentication cookie:

Protected Sub cmdSignOut_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles cmdSignOut.Click

FormsAuthentication.SignOut()
Response.Redirect("~/Login.aspx")
End Sub


4.3. Persistent Cookies

In some situations, you may be using the forms authentication login for personalization instead of security. In this situation, you may decide to allow persistent cookies. A persistent authentication cookie remains on the user's hard drive and keeps the user signed in for hours, days, or weeks—even if the user closes and reopens the browser.

Creating a persistent cookie requires a bit more code than creating a standard forms authentication cookie. Instead of using the RedirectFromLoginPage() method, you need to manually create the authentication ticket, set its expiration time, encrypt it, attach it to the request, and then redirect the user to the requested page. All of these tasks are easy, but it's important to perform them all in the correct order. (When using nonpersistent cookies, the RedirectFromLoginPage() takes care of all these tasks automatically.)

Persistent cookies also present a potential security risk, because another user could use the same computer to access the secured pages, without being forced to log in. If you want to allow the user to create a persistent cookie, you should make it optional, because the user may want to access your site from a public or shared computer. Generally, sites that use this technique include a check box with text such as Keep Me Logged In.

The following code examines a check box named chkPersist. If it's selected, the code creates a persistent cookie that lasts for 20 days (although you can change this detail to whatever time interval you like).

' Perform the authentication.
If txtPassword.Text.ToLower() = "secret" Then
If chkPersist.Checked Then
' Use a persistent cookie that lasts 20 days.
' The timeout must be specified as a number of minutes.
Dim timeout As Integer
timeout = CInt(TimeSpan.FromDays(20).TotalMinutes)

' Create an authentication ticket.
Dim ticket As New FormsAuthenticationTicket(txtName.Text, _
True, cookietimeout)

' Encrypt the ticket (so people can't steal it as it travels over
' the Internet).
Dim encryptedTicket As String = FormsAuthentication.Encrypt(ticket)

' Create the cookie for the ticket, and put the ticket inside.
Dim cookie As New HttpCookie(FormsAuthentication.FormsCookieName, _
encryptedTicket)
' Give the cookie and the authentication ticket the same expiration.
cookie.Expires = ticket.Expiration

' Attach the cookie to the current response. It will now travel back to
' the client, and then back to the web server with every new request.
HttpContext.Current.Response.Cookies.Set(cookie)

' Send the user to the originally requested page.
Dim requestedPage As String
requestedPage = FormsAuthentication.GetRedirectUrl(txtName.text, False)
Response.Redirect(requestedPage, True)
Else
' Use the standard authentication method.


FormsAuthentication.RedirectFromLoginPage(txtName.Text, False)
End If
End If

It's worth noting that the FormsAuthentication.SignOut() method will always remove the forms authentication cookie, regardless of whether it is a normal cookie or a persistent cookie.

Other  
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us
programming4us
 
 
programming4us