Now many people will argue that it is a stupid idea to store clear text credentials in web.config, and in some respects they are right. Obviously the credentials for the website is as clear as day, BUT .config files are not served by ASP.NET, so there are some precautions in place.
But if you are writing a test app for the Membership provider and you really can’t be bothered with setting up a SQL Local Data Source and really just want to get your proof of concept out of the way, it really is brilliant.
However, although you normally set up Membership once per project, I became a little bit rusty on the allow and deny elements for the credentials section in Web.config. Here is a typical section to configure Forms authentication with a user account
<authentication mode="Forms">
<forms loginUrl="~/Login/Login.aspx" timeout="20">
<credentials>
<user name="Administrator" password="p@ssw0rd1"/>
</credentials>
</forms>
</authentication>
The website I was setting up wanted to disallow access to the root directory, and force users to go into the ~/Login/Login.aspx before being allowed access to the root directory.The Login.aspx page only contains a single Login Control to save me time.
The Home.aspx just says “Hello, <username>”, using the LoginName control.

Here is my project setup:
So lets start with the easy one - the ~/Login/Web.config. We want to allow all users access, so the web.config has a single entry:
<configuration>
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</configuration>
The reason we are saying allow everyone is for 2 reasons:
- All users should have the ability to log in and out.
- The root will have permissions denying anonymous users. This directory will inherit those permissions if none are specified, so we need to override it.
Secondly, we MUST OVERRIDE the default implementation of the Login Control. We do this by double clicking on the Login Control and override the _Authenticate method as follows:
if (FormsAuthentication.Authenticate(this.Login1.UserName, this.Login1.Password))
FormsAuthentication.RedirectFromLoginPage(this.Login1.UserName, false);
else
this.Login1.FailureText = "Invalid username or password. Sorry!";
The reason you must do this is by default, ASP.NET will try and connect to the LocalSqlServer connection string, hidden in the default web.config (in the .NET folder). Since I am not using SQL Server, I need to override it, and it now ‘knows’ that my web.config takes precedence.
So now it is logging me in properly, we need to work out the authorization needed for the root directory, as only authenticated users are can access it.
Now, we need to tell the ~/Web.config to allow Authenticated users, which is equivalent to denying ANONYMOUS users. In the users attribute, the symbol ? means ANONYMOUS (as in who are you?). So out of pot luck, you might try the following:
<authorization>
<allow users="?"/> <!-- Allow anonymous users -->
<deny users="*"/> <!-- Deny everyone -->
</authorization>
ASP.NET will do the following:
- Is the user authenticated? NO –> allow access to home page.
- Is the user authenticated? YES –> redirect them to the login page.
That is definitely not what we want! Only allow access AFTER they are authenticated. So how about:
<authorization>
<deny users="?"/> <!-- Deny anonymous users -->
<allow users="*"/> <!-- Allow everyone 'else' -->
</authorization>
This is what we want. We are denying anonymous users and allowing everyone else.
Although I have added the second line, it is not required. By default it allows everyone access unless otherwise specified. Since rules are processed sequentially, once a match is found, the matching stops. Therefore an entry like:
<authorization>
<deny users="*"/> <!-- Deny all users -->
<allow users="*"/> <!-- Allow all users [from machine.config] -->
</authorization>
This will always deny users, because this match will occur first, and therefore the allow will never get hit.