As you may already know, I’ve been writing a set of Generic Db (Sql-92) Providers for Membership, Roles, Profiles, and Personalization, and am nearly done.
Since the primary purpose of the Membership and Roles providers is to provide Authentication on your website, and use it to limit access to certain directories (Authorization), I’m going to go over the two parts again below.
Authentication, Roles, and Authorization are distinct services.
Although Authentication is almost always used in conjunction with other services, such as Roles, or Authorization, it is important to recognize that Authentication is only the process of recognizing a returning user to your website, no more, no less.
One can then use other services to assign Roles to an Authenticated user, and/or use Authorization to limit access to specific users and/or roles.
Because there is no meaningful way of setting up Authentication without setting up Roles and/or Authorization, they are always discussed together (but that doesn’t make them the same thing).
Authentication
The first step is always authentication, which you can setup in one of the following Modes:
- None
- Forms (ie Forms Authentication),
- Windows (Windows NT authentication, used with any IIS authentication (Basic, Digest, Integrated Windows authentication ( NTLM/Kerberos ), or certificates.
- Passport (Microsoft Passport Authentication).
Intranet websites often use Windows authentication, and 9 times out of 10, websites that are intended for public use will use the Forms authentication mode.
We’ll not be discussing the Windows mode, and instead be focusing only on the Forms mode.
Setting up a Forms Authentication environment
To set up Forms authentication environment, we have to do the following steps:
- add an authentication element to the web.config file
- create a login.aspx page, with a asp:login control on it.
- define a list of Users.
The simplest example of such a setup would be the following two snippets:
1. A really rudimentary login.aspx page:
<%@ Page Language="C#" AutoEventWireup="true" %>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<h5>Login Please:</h5>
<form id="form1" runat="server">
<div>
<asp:Login runat="server"/>
</div>
</form>
</body>
</html>
2. A minimalist root web.config authentication section:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" protection="All" timeout="30" path="/" />
</authentication>
Note that the above authentication section is doing the following:
- specifying that the mode=Forms,
- specifying that the page that non-authenticated users are redirected to is called login.aspx
- the optional protection attribute is described in full here, but you can safely omit it for most purposes.
- the timeout is self-evident.
- the Path is optional, but important to consider (I generally would set it):
Specifies the path for cookies that are issued by the application.
The default is a slash (/), because most browsers are case-sensitive and will not send cookies back, if there is a path case mismatch.
3. The above is not complete: you’ve defined the system by which to authenticate, but you still need to define an actual list of users/passwords to authenticate against.
The simplest solution (but not the best -- see further down) is to define a list of users/passwords directly within the web.config by adding a credentials element to the forms element:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" protection="All" timeout="30" path="/">
<credentials passwordFormat="Clear">
<user name="user1" password="0000" />
<user name="user2" password="1111" />
</credentials>
</forms>
</authentication>
Note
Obviously this way of adding users/passwords is rudimentary: one can only setup a very small list of users in the web.config, and the list is not dynamic, so the above solution is never really used in a real life situation (one would use a Membership Provider instead, which we will be presenting at the bottom).
How it works - the Authenticate process
We have a login form, and we have a list of users/passwords, but if you try it out, you can click the Login control’s submit button until you are blue in the face without getting past it.
That is because you have a form, and you have a list – but nobody is actually checking against the list.
You do this by by handling the Authenticate event of the Login control, and from there calling a method of the FormsAuthentication static class to check the name and password against the credentials in the system.web file.
MSDN Documentation:
- "The Authenticate event is raised when a user uses the Login control to log in to a Web site.
Custom authentication schemes can use the Authenticate event to authenticate users."
- "Custom authentication schemes should set the Authenticated property to true to indicate that a user has been authenticated."
- "When a user submits his or her login information, the Login control first raises the LoggingIn event, then the Authenticate event, and finally the LoggedIn event."
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e){
string userName = uiLogin.UserName;
string password = uiLogin.Password;
//Note:
//By setting the return value, the form
//will automatically be Response.Redirected to the original page.
e.Authenticated =
FormsAuthentication.Authenticate(userName, password);
}
If the Authenticate helper method says its ok, remember to set the e.Authenticated return flag, so that the Login control then continues to by building an Identity cookie and redirect the page to the original page, as demonstrated in the following proxy code:
class Login: CompositeControl {
void AttemptLogin(string, string){
..raise.
if (args2.Authenticated){
FormsAuthentication.SetAuthCookie(
this.UserNameInternal,
this.RememberMeSet);
this.OnLoggedIn(EventArgs.Empty);
this.Page.Response.Redirect(this.GetRedirectUrl(), false);
}
...
}
}
&l ...
Read More »