|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionFor a real-world Enterprise application, security plays an important role. Forms-based authentication is a popular technique used by many Web sites. With ASP.NET, writing forms authentication is like a breeze. Forms Authentication provider in ASP.NET exposes cookies-based authentication services to applications. But for some of the applications due to the nature of the security requirements, Forms Authentication provider is not a very good fit. Writing your own Custom Authentication provider offers a solution for such applications. With very little code and effort, you can have a role-based authentication system that is platform-agnostic. Background: Forms Authentication provider - Not a good fitLets take a scenario - An application wants to store the following information for a User:
Forms Authentication provider uses the Listing 1 - Login.aspx//Validate User
//SecurityManager is a helper class of your application
if(SecurityManager.ValidateLogin(txtUserName.Text, txtPassword.Text))
{
//Get a CustomIdentity object with all the details
//for the authenticated user
CustomIdentity identity = SecurityManager.GetUserIdentity(
txtUserName.Text);
if(identity != null && identity.IsAuthenticated)
{
//Get user Roles
ArrayList roles = SecurityManager.GetUserRoles(txtUserName.Text);
//Create a CustomPrincipal object
CustomPrincipal newUser = new CustomPrincipal(identity, roles);
Context.User = newUser;
//Redirect user to the requested page
FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, False);
}
}
The code in Global.asax will be something like this (Listing 2): Listing 2 - Global.asax.cs//Implement an Authentication Request Handler to Construct
// a GenericPrincipal Object
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookie[
FormsAuthentication.FormsCookieName];
if(authCookie != null)
{
//Extract the forms authentication cookie
FormsAuthenticationTicket authTicket =
FormsAuthentication.Decrypt(authCookie.Value);
// Create an Identity object
CustomIdentity id = SecurityManager.GetUserIdentity(authTicket.Name);
//Get user Roles
ArrayList roles = SecurityManager.GetUserRoles(txtUserName.Text);
//Create a CustomPrincipal object
CustomPrincipal newUser = new CustomPrincipal(identity, roles);
Context.User = newUser;
}
}
For more details on the above example please visit MSDN - How To: Implement Iprincipal This approach works fine for some applications but think of the unnecessary overhead it has in retrieving the user details on each Request. If your application can live with such a design than be it. But for some of the very interactive, performance savvy applications, this approach is not suitable. Here, writing a Custom Authentication provider serves the purpose. Custom Authentication moduleImplementing the
Listing 3 - Web.config<!-- Entries required for CustomAuthenticationModule -->
<appSettings>
<!-- Parameter for the Login page URL (Required) -->
<add key="CustomAuthentication.LoginUrl" value="/Login.aspx" />
<!-- Parameter for the Authentication cookie Name (Required) -->
<add key="CustomAuthentication.Cookie.Name" value=".CUSTOM_AUTH" />
<!-- Parameter for Timeout for Cookie expiration in minutes
(Optional- persist cookie across browser sessions) -->
<add key="CustomAuthentication.Cookie.Timeout" value="2" />
</appSettings>
Sample ApplicationThere is a sample application, which uses this CustomAuthentication module. To add a custom Listing 4 - Web.config<!-- Add a Custom Authentication module -->
<httpModules>
<add name="CustomAuthenticationModule"
type="CustomSecurity.CustomAuthenticationModule, CustomSecurity" />
</httpModules>
Add the required entries for CustomAuthenticationModule as given above in Listing 3. Please see the required code in login page. This is the only code you need to write (Listing 5). Listing 5 - Login.aspx//Write your own Authentication logic here
if(this.username.Text != "" && this.password.Text !="")
{
//Write your own code to get the User Roles
ArrayList roles = new ArrayList();
roles.Add("Manager");
if(this.username.Text == "superuser")
roles.Add("Administrator");
roles.Add("ITUser");
//Convert roles into pipe "|" separated string
System.Text.StringBuilder strRoles = new System.Text.StringBuilder();
foreach(string role in roles)
{
strRoles.Append(role);
strRoles.Append("|");
}
//Create a CustomIdentity object
CustomIdentity userIdentity = new CustomIdentity(this.username.Text,
1, true, true, this.username.Text,
"someuser@some.com", strRoles.ToString());
//Create a CustomPrincipal object
CustomPrincipal principal = new CustomPrincipal(userIdentity, roles);
Context.User = principal;
//Redirect user
CustomAuthentication.RedirectFromLoginPage(userIdentity);
}
You can access the Listing 6 - Home.aspx//Get the CustomIdentity in aspx pages from the HttpContext
this.user1.Text = ((CustomIdentity)Context.User.Identity).UserFullName;
//Get the CustomIdentity in any class in middle layer from the Thread
this.user2.Text = ((CustomIdentity)
Thread.CurrentPrincipal.Identity).UserFullName;
role.Text = Thread.CurrentPrincipal.IsInRole("Administrator").ToString();
|
||||||||||||||||||||||