Application Security Testing: An Integral Part of DevOps
If you've created a Web application in Visual Studio .NET, you should be aware that—by default—anyone can access your pages. However, there is a way to keep nosy, unwanted types out. It's called authentication.
ASP.NET includes support for three core types of authentication: Windows, which allows only certain Windows accounts to access a page; Passport, which uses the Microsoft Passport universal login system to verify a user (a pay service); and Forms, the most popular method of authentication, which we'll be covering here.
Want to set up ASP.NET Forms authentication? Just follow my five quick and easy steps.
- Open the Web.config file in your Solution. This stores a number of settings for your Web application. Edit the <authentication> element so that it reads something like the following. (Alter usernames and passwords as appropriate, and watch both your casing and spacing.) This provides your application with a list of valid users.
<authentication mode="Forms"> <forms> <credentials passwordFormat="Clear"> <user name="test1" password="password" /> <user name="test2" password="password" /> </credentials> </forms> </authentication>
- Still in the Web.config file, remove the <allow users="*" /> line from within the <authorization> element. This line grants access to anyone, and we've just erased it.
- Still within the <authorization> element, add the following line to deny access to all unknown users (that is, those not authenticated):
- Create a page called login.aspx. By default, all unauthenticated users will be redirected to this page. Add TextBox controls (txtUsername and txtPassword) for your browser to supply credentials. Also, add a CheckBox control (chkPersist) to be used if the user wants his or her machine to automatically log them in next time.
- Behind a login button on your login.aspx page, add code similar to the following to authenticate your user:
<deny users="?" />
If System.Web.Security.FormsAuthentication.Authenticate( _ txtUsername.Text, txtPassword.Text) = True Then System.Web.Security.FormsAuthentication.RedirectFromLogin _ Page(txtUsername.Text, chkPersist.Checked) Else Response.Write("Invalid credentials - go back and try _ again!") End If
And that's it! Now, whenever a user visits a page in your application—and they're unauthenticated—they'll be redirected to login.aspx. From there, they'll be able to provide credentials. The .Authenticate method attempts to match these with a valid username and password combination in Web.config. If the credentials are invalid, a generic error message is displayed. If everything is fine, the .RedirectFromLoginPage method runs, taking the username and whether the login "persists" (that is, is remembered by the computer between sessions) as arguments, and then sends the user back to the initially requested page.
After this, whenever you need to refer back to the username, simply check out the User.Identity.Name property. And, when the user requests to explicitly log out, run code similar to the following:
Top Tip: If you don't want to use login.aspx as your login form, you can change the page by adding a loginUrl attribute to the <forms> element of your Web.config file. For example, the following tag makes myloginpage.aspx the default login page: <forms loginUrl="myloginpage.aspx" />.
Figure: Authentication kicking in, as I try to access a restricted page
Forms Authentication, Without Web.config
The sort of Forms authentication discussed above is, however, relatively limited. Unless you have just a few core user groups, which can be easily stored in Web.config, it's not awfully useful. And the passwords are stored in plain text XML, which means that anyone in your development team could retrieve them (unless you encrypt to MD5 format and change the passwordFormat attribute).
So, how can you authenticate users using information from a database, say?
It's easy: simply omit the .Authentication method in the procedure. In its place, add your own code, perhaps querying a table using ADO.NET code and validate the provided information. If it's acceptable, run the .RedirectFromLoginPage method. Everything else will work as normal.
Note that, if you want to remove the sample users from your Web.config file, you need to replace the whole <authentication><form>...</authentication> section with just <authentication mode="Forms" />.
Authenticating Just Part of Your Site
Sometimes, you don't want to authenticate all of your Web application. In some situations, you may just want to keep a couple of pages, such as a basket checkout form, available to only those authorized users.
Yes, you could try doing it manually by remembering some sort of session variable and/or by using cookies. But a much neater solution is to use a little-known trick that allows you to still use ASP.NET Forms authentication, but only with an exclusive number of pages on your site.
- Alter your Web.config file so that it uses Forms authentication. You can do this by following the first step in the "Five Steps to ASP.NET Authentication" tip, if you'll be using Web.config to store the users. Or, simply change the <authentication> element to <authentication mode="Forms" /> if you're going to authenticate using your own database, et cetera. In this tip, however, we're not going to deny regular, unauthenticated visitors.
- Still in your Web.config file, just underneath the <configuration> element, add the following code, replacing "checkout.aspx" with the page you want to protect. This will ensure that ASP.NET denies access to any unauthenticated users attempting to view this page. You can add as many <location> blocks as you wish and can include filenames and folders in the path.
- Go ahead and create your login.aspx page as you did in the last tip.
<location path="checkout.aspx"> <system.web> <authorization> <deny users="?" /> </authorization> </system.web> </location>
And that's it! You've created a Web application that uses Forms authentication but grants access to all users by default. You've then added a clause in Web.config that states all those users who are attempting to view checkout.aspx must be authorized first—and are therefore redirected to login.aspx when they access the page.
Note that these changes to the Web.config file are the only real difference to the authentication process. The other methods of logging out, retrieving the username, and so on all work in exactly the same way as with full authentication.
About the Author
Karl Moore (MCSD, MVP) is an experience author living in Yorkshire, England. He is author of numerous technology books, including the new Ultimate VB .NET and ASP.NET Code Book, plus regularly features at industry conferences and on BBC radio. Moore also runs his own creative consultancy, White Cliff Computing Ltd. Visit his official Web site at www.karlmoore.com.