ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Exclusive offer: get 50% off this eBook here
ASP.NET 3.5 CMS Development

ASP.NET 3.5 CMS Development — Save 50%

Build, Manage, and Extend your own Content Management System

$23.99    $12.00
by Jeff Cochran | June 2009 | Content Management Open Source

In this article by Jeff Cochran, we will be discussing about how to add security and membership to a Content Management system. we will divide this article in two parts. In this first part, we will cover configuring and using forms authentication, along with how to create the membership database and the login page.

Security is a concern in any web application, but the security this article deals with is that of user accounts, membership, and roles. We'll be using the ASP.NET membership and roles functions to allow certain users such as administrators to perform specific tasks. These tasks may include managing the application, while other users such as content editors, may be restricted to the specific tasks we want them to manage such as adding or changing content. User account management can be handled either by the application (in our case, our Content Management System) or by Windows itself, using standard Windows authentication functions, as well as file and folder permissions.

The advantage of an application-based user authentication system is primarily in cost. To use Windows authentication, we need to purchase Client Access Licenses (CALs) for each user that will access our application. This is practical in an intranet, where users would have these licenses to perform other functions in the network. However, for an Internet application, with potentially thousands of users, licensing could be extremely expensive.

The drawback to an application-based system is that there is a lot more work to do in designing and using it. The Windows authentication process has been around for years, continually improved by Microsoft with each Windows release. It scales extremely well, and with Active Directory, can be extended to manage just about anything you can think of.

ASP.NET membership

Fortunately, Microsoft has provided relief for application-based authentication drawbacks in the 2.0 version of the ASP.NET framework, with the ASP.NET membership functions, and in our case, the SqlMembershipProvider. The membership API makes it simple for us to use forms authentication in our application, retrieving authentication and membership information from a membership provider. The membership provider abstracts the membership details from the membership storage source. Microsoft provides two providers—the ActiveDirectoryMembershipProvider that uses Active Directory and the SqlMembershipProvider that uses an SQL server database for the user data store.

By default, ASP.NET authentication uses cookies—small text files stored on the user's system—to maintain authentication status throughout the application. These cookies normally have an expiration time and date, which requires users to log in again after the cookie has expired. It is possible to use cookies to allow the client system to authenticate the application without a user login, commonly seen as a "Remember Me" checkbox in many web site login pages. There is naturally a downside to cookies in that a client system may not accept cookies. ASP.NET can encode the authentication information into the URL to bypass this restriction on cookies. Although in the case of our application, we will stick with the cookie method. Forms authentication secures only ASP.NET pages. Unless you are using IIS7, and the integrated pipeline, where ASP.NET processes all file requests, the ASP.NET DLL won't be called for non-ASP.NET pages. This means that you cannot easily secure HTML pages, PDF files, or anything other than ASP.NET through forms authentication.

Configuring and using forms authentication

Let's start learning ASP.NET forms authentication by walking through a brand new application. We'll then add it to our Content Management System application. Forms authentication is actually quite simple, both in concept and execution, and a simple application can explain it better than adopting our current CMS application. Of course, we eventually need to integrate authentication into our CMS application, but this is also easier once you understand the principles and techniques we'll be using.

Creating a new application

Start by opening Visual Web Developer 2008 Express and creating a new web site by clicking on File | New Web Site. Use the ASP.NET Website template, choose File System, and name the folder FormsDemo.

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

When the site is created, you are presented with a Default.aspx page created with generic code. We will use this as our home page for the new site, although we need to modify it for our needs.

Creating the home page

Visual Web Developer 2008 Express creates a generic Default.aspx file whenever you create a new site. Unfortunately, the generic file is not what we want and will need modification. The first thing we want to do is make sure our site uses a Master Page, just as our Content Management System application will. To do this, we could delete the page, create our Master Page, and then add a new Default.aspx page that uses our Master Page. In the case of a brand new site, it's pretty easy, but what if you have developed an extensive site that you want to convert to Master Pages? You would want to add a Master Page to an existing site, so let's go ahead and do that.

Create the Master Page

To create a Master Page, leave the Default.aspx file open and press Ctrl+Shift+A to add a new item to the solution. Choose the Master Page template and leave the name as MasterPage.Master. Place the code in a separate file and click Add to create the Master Page. You will notice that this creates the same generic code as in the previous chapter. Unfortunately, our Default.aspx file is not a content page and won't use the MasterPage.Master we just created, unless we tell it to.

To tell our Default.aspx page to use the MasterPage.Master, we need to add the MasterPageFile declaration, in the @ Page declaration, at the top of the file. Add the following code between the Language and AutoEventWireup declarations:

MasterPageFile="~/MasterPage.master"

This adds the Master Page to our Default.aspx page. However, content pages include only those Content controls that match the Master Page, not the full page code as our Default.aspx page currently does. To fix this, replace the remaining code outside the @ Page declaration with the following two Content controls:

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<h1>This is where the content goes.</h1>
</asp:Content>

We've left the Content1 control empty for the moment, and we've added a simple text statement to the Content2 control so that it can be tested. If you view the Default.aspx page in a browser, you should see the relatively uninteresting web page below:

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Enabling forms authentication

Okay, we have a boring home page for our new site. Let's leave it for a moment and enable forms authentication for the site, so we can restrict who can access our home page. The process of enabling forms authentication is simply adding a few lines to our web.config file. Or in the case of the generic web.config file, which we created while creating our new site, we simply need to alter a single line.

Open the web.config file in the new site and look for the line that says:

<authentication mode="Windows" />

Edit it to read:

<authentication mode="Forms" />

Save the web.config file and you have now enabled forms authentication for this site.

The default authentication mode for ASP.NET applications is Windows, which is fine if you're working in an intranet environment where every user probably has a Windows login for use in the corporate network anyway. Using Windows authentication, Windows itself handles all the security and authentication, and you can use the myriad of Windows utilities and functions such as Active Directory, to manage your users.

On the other hand, with forms authentication, ASP.NET is expected to handle all the details of authentication and security. While ASP.NET 2.0 and later have sophisticated membership and profile capabilities, there is no ASP.NET mechanism for protecting files and folders from direct access, outside of the application. You will still need to secure the physical server and operating system from outside of your application.

Creating the membership database

To use forms authentication and the SqlMembershipProvider, we need to create a database to authenticate against. This database will hold our user information, as well as membership information, so we can both authenticate the user and provide access based on membership in specific roles. For our demonstration, we will create a new database for this function.

We'll create a database with SQL Server ManagementExpress, so open it and right-click Databases in the Object Explorer pane. Choose New Database and name it FormsDemo. Change the location of the database path to the App_Data folder of your FormsDemo web application—the default is C:InetpubFormsDemoApp_Data as shown below. Click OK and the new database will be created.

If you look at this database, you will see that it is empty. We haven't added any tables to it, and we haven't set up any fields in those non-existent tables. The database is pretty much useless at this stage. We need to create the database layout, or schema, to hold all the authentication and membership details. Fortunately, Microsoft provides a simple utility to accomplish this task for the 2.0 version of the ASP.NET framework – aspnet_regsql.exe. We'll use this too, in order to create the schema for us, and make our database ready for authentication and membership in our application.

To use aspnet_regsql.exe, we need to provide the SQL Server name and login information. This is the same information as shown in the login dialog when we open the database in SQL Server Management Studio Express, as shown below:

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Note the server name, it will usually be {SystemName}/SQLEXPRESS, but it may be different depending on how you set it up. We use SQL Server Authentication with the sa account and a password of SimpleCMS when we set up SQL Server Express 2005, and that's what we'll use when we run the aspnet_regsql.exe tool.

To run aspnet_regsql.exe, you may browse to it in Windows Explorer, or enter the path into the Run dialog when you click on Start and then Run. The default path is C:WINDOWSMicrosoft.NETFrameworkv2.0.50727aspnet_regsql.exe. The utility may be run with command-line arguments, useful when scripting the tool or using it in a batch file, but simply running it with no parameters brings it up in a GUI mode. When the ASP.NET SQL Server Setup Wizard launches, click Next. Make sure that the Configure SQL Server for application services is selected and click on Next.

The ASP.NET SQL Server Setup Wizard will ask for the server, authentication, and database. You should enter these according to the information from above.

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Click Next to confirm the settings. Click Next again to configure the database with the ASP.NET users and membership schema. Continue and exit the wizard, and the database is ready for us to use for authentication. If you were to open the FormsDemo database in SQL Server Management Studio Express, you would find that new tables, views, and stored procedures have been added to the database during this configuration process.

ASP.NET 3.5 CMS Development Build, Manage, and Extend your own Content Management System
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

Configuring the SqlMembershipProvider

Our database is ready to use, but our application is not—at least not yet. We need to add a connection string in our web.config file so that we can connect to the database. We also need to add the SqlMembershipProvider information so that our application can access the database and use the new functions provided in our schema.

Open the web.config file in Visual Web Developer 2008 and find the default section that looks like:

<connectionStrings>
<add name="FormsDemoConnectionString"
connectionString="Data Source=.SQLEXPRESS;
AttachDbFilename=C:InetpubFormsDemoApp_DataFormsDemo.mdf;
Initial Catalog=FormsDemo.mdf;
User ID=sa;
Password=SimpleCMS"
/>
</connectionStrings>

Replace it with:

<authentication mode="Forms" />

This will configure the database connection string so that we can use the database.

To configure the SqlMembershipProvider, we need to add the AspNetSqlMembershipProvider to the Providers section of the Membership section, none of which we have in the default web.config. Immediately below the line that reads:

<membership defaultProvider="FormsDemoSqlMembershipProvider"> 
<providers>
<add name="FormsDemoSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider,
System.Web, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="FormsDemoConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
/>
</providers>
</membership>

add the following code:

passwordStrengthRegularExpression="@"(?=.{6,})(?=(.*d){1,})(?=(.*W){1,})"

This provides the basic settings we need for our application. There are a few settings to take note of though:

  • defaultProvider: We have designated a default provider for our application, as the machine.config file on our server uses AspNetSqlMembershipProvider as the default and expects a database named aspnet.mdb in the App_Data folder. Had we not created our own database and added the schema to it, aspnet.mdb would be the auto-created database. We do not want this for two reasons. The first is that every automatically configured application on the server would have the same database name. Also, it's easy to mix up database backups and maintenance schemes. More important though is that we have complete control and flexibility by creating our own database. The ASP.NET membership framework allows multiple providers so that we could split providers between databases for example. By specifically naming and creating our own database, and using it as the default for this application, we maintain explicit control.
  • applicationName: We have set the applicationName to the root of the web application, which is what we want in this case. But this may not be where our application is located in a more complex application, and specifying the applicationName here would again provide us more explicit functionality. If we had not configured this, it would be set to the application root anyway. However, here we maintain control over it, as in the future, we may move the application.
  • enablePasswordRetrieval, enablePasswordReset, requiresQuestionAndAnswer : These three are related, and set to the defaults. They determine whether a user can retrieve their password, reset their password, and whether or not answering a security question is required to perform either of those two functions. The default setting for these providers doesn't allow a user to retrieve his/her password because those would be sent to the user and could already be stolen by a hacker, but it allows a user to reset his/her password to a temporary one that can immediately be changed to the one known only by the user.

You also need to understand that these are defaults only in the SqlMembershipProvider we used, not the auto-created AspNetSqlMembershipProvider.

Password complexity in ASP.NET applications
ASP.NET password complexity often confuses both users and programmers. It is in the SqlMembershipProvider that the complexity is controlled. The default is a password with a minimum of seven characters, one of which must be non-alphanumeric, or not a number or letter. This means the password Passw0rd—which has eight characters, has both upper and lower case, and contains a zero—doesn't meet the default requirements because it doesn't contain a non-alphanumeric character. The password password! does meet the requirements, even though it has only lower case letters and no numbers. This is because the password has seven or more characters, and one of them, the exclamation point, is nonalphanumeric. You must decide on how complex you will require user passwords to be. More complex is more secure, but harder for users to deal with. At some point, security requirements become annoyances to the user and they will stop using your site. You may also use the passwordStrengthRegularExpression parameter to further refine your password strength, although the default is not to use it, leaving the expression blank. For example, the following code would require a password of at least seven characters, including one number and one non-alphanumeric character:
passwordStrengthRegularExpression="@"(?=.{6,})(?=(.*d){1,})(?=(.*W){1,})"
You can find more about these, along with other SqlmembershipProvider properties, at http://msdn.microsoft.com/en-us/library/system.web.security.sqlmembershipprovider_properties.aspx.

Creating the login page

The first step to providing an authentication for users is creating a page for them to use to log into our application. The default name of this page for ASP.NET forms authentication is Login.aspx and we will stick to the defaults for this demonstration. So, start by adding a new item to our application in Visual Web Developer 2008 Express and choosing the Web Form template, naming it Login.aspx and selecting the MasterPage.master as your Master Page.

To add the login control to the page, enter the following code inside the Content2 ContentPlaceHolder control:

<asp:Login ID="Login1" 
runat="server">
</asp:Login>

If you save the Login.aspx file and run it in a web browser, you should see a page similar to this:

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Changing the default login page

ASP.NET uses a default login page Login.aspx, and this is the URL that an unauthenticated user is redirected to when they try to access a page that requires authentication. To change this page name, we simply need to alter the authentication section of the web.config. The default web.config, and the one we used here, has a line similar to this:

<authentication mode="Forms" />

If we change this to:

<authentication mode="Forms">
<forms loginUrl="UserLogin.aspx" />
</authentication>

Our application will then expect a page file named UserLogin.aspx and will use that as the login page for this application. We could also change the URL that logged in users are sent to if none is specified by using the defaultUrl parameter, similar to:

<authentication mode="Forms">
<forms loginUrl="UserLogin.aspx"
DefaultUrl="MembersPage.aspx" />
</authentication>

Although we have ignored these settings for this demo, good programming practices would include specifying these in the web.config for an application so that application doesn't accidentally inherit incorrect settings after deployment to a server with other applications on it.

Of course, if you try to log in using the Login.aspx page we just created, nothing will happen. We don't have a user account to log in with, so, let's create a quick one to test our logins.

Creating a user account with the ASP.NET configuration tool

Visual Web Developer 2008 Express has a built-in tool to help configure several different aspects of your application and IIS installation. We're going to use it to manage security by creating a new user account for accessing our web site. In Visual Web Developer, click on Website, and then ASP.NET Configuration. When the utility opens, click on the Security tab and you'll see a screen like this:

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

We have already created the database to store our user accounts in and we just need to create a user, so click on Create user and fill in the form on the following page, as shown below. Enter a User Name of User1, with a Password of Password!. Enter a valid email address, a Security Question of First Pet, and a pet's name such as Goldie. Click Create User, and after a couple of moments, you should get a confirmation that the user was created.

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Windows authentication
In our application, we are using forms authentication to provide the security we need. We could use Windows authentication in a similar manner, for example in an intranet where users would normally already have Windows accounts. In Windows authentication, Windows users and groups take the place of user accounts and roles in forms authentication. You would create users and groups in Windows to be used to grant access to the application. Assigning user accounts to the groups would allow those users the access provided by group membership. Note that the Web Site Administration Tool cannot be used to manage users and groups in a Windows authentication application. You need to use the tools provided by Windows such as Active Directory. The advantage of Windows authentication is obvious—we have a single directory of users and access groups for all functions within your network. The disadvantage is the licensing costs of all those user accounts, if the only function they are needed for is to provide access to a single application.

Creating a login

Okay, we've created a user and we have a login page to log that user in. But why would a user log into our application? That's right, to reach pages or content that are restricted to logged in users. In our application, we will be restricting access to content based on whether a user has logged in or not. To do this, we make use of a LoginStatus control. This control will let us know the current status of the page viewer and also provide a way for that viewer to log into our application for further access.

Open the home page Default.aspx in Visual Web Developer, and locate the Content2 ContentPlaceHolder control. Immediately before the <h1> tag, enter the following code:

<asp:LoginStatus ID="LoginStatus1" runat="server" />

That's it, just one line of code. Doesn't ASP.NET make this simple? When you save the file and run it in a browser, you should see a page like this:

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Click on that little Login link and you'll see the Login.aspx page displayed, as that is the default login page for the ASP.NET login control. It will look similar to this:

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

Enter a user name of User1 and a password of Password!, as we used when creating our user account. You will then be authenticated and returned to the home page, where the login link has now become a Logout link, as shown below:

ASP.NET 3.5 CMS: Adding Security and Membership (Part 1)

So, with a few lines of ASP.NET code, we have created an authentication system for our application.

Summary

In this first part of the article we saw how to create Forms authentication and how to use it, along with how to create home page, Master Page, and login page. The next part of the article will focus on adding Forms authentication to our CMS, along with creating user accounts and assigning membership roles.

If you have read this article you may be interested to view :

ASP.NET 3.5 CMS Development Build, Manage, and Extend your own Content Management System
Published: June 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Jeff Cochran

Jeff Cochran is a Senior Network Specialist for the City of Naples, Florida. A large part of his job includes web design and coding, as well as web server management. Jeff has nearly two decades of experience with the Internet, having started one of the first Internet Service Providers in Southwest Florida, and has worked with Windows and Unix-based web servers. Now primarily concentrating on Windows technologies, Jeff has been a Microsoft MVP for Microsoft's Internet Information Server for nearly a decade and is active in the ASP Classic and ASP.NET communities as well.

Jeff has been married for twenty years to Zina, a graphic designer and, according to most accounts, the driving force that keeps him focused on… Oh look – A Pony! In the off-hours, Jeff and Zina spend much of their time remodeling a 1950s bungalow in Naples, Florida, trying to keep the rain out and the cats in. Jeff also has a long-term addiction to classic pinball machines, tropical fish, and off-road vehicles, all of which compete with home repairs for a share of his income.

Books From Packt

Choosing an Open Source CMS: Beginner's Guide
Choosing an Open Source CMS: Beginner's Guide

Drupal 5 Views Recipes
Drupal 5 Views Recipes

JBoss Tools 3 Developers Guide
JBoss Tools 3 Developers Guide

WordPress 2.7 Cookbook
WordPress 2.7 Cookbook

Plone 3 Theming
Plone 3 Theming

Drupal 6 Content Administration
Drupal 6 Content Administration

Apache Struts 2 Web Application Development
Apache Struts 2 Web Application Development

Alfresco 3 Enterprise Content Management Implementation
Alfresco 3 Enterprise Content Management Implementation

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software