Just a quick “request” post covering the basics of caching user roles in an ASP.NET application using forms based authentication.
Role based authentication & authorisation is an important part of most modern web applications. After successful authentication of a user, an authorisation process must take place to determine which areas of the application the user has access to.
To implement the basic role based security, there are three points to be considered. In this example we are returning a list of roles from a database for a particular user.
We can then add a web.config to each directory we wish to protect in the following format.
<authorization> <allow roles="role1,role2"></allow>
<deny users="*"></deny></authorization>
Application_AuthenticateRequest is defined in Global.asax and will be accessed each time a web request is made if your application. In order to save a database trip for each time you’re grabbing your roles, it’s best to use a cached mechanism for this:
Try If HttpContext.Current.User IsNot Nothing Then If HttpContext.Current.User.Identity.IsAuthenticated Then If HttpContext.Current.User.Identity.AuthenticationType <> "Forms" Then Throw New Exception(String.Format("You attempted to authenticate with {0} but only forms authentication is accepted.", HttpContext.Current.User.Identity.AuthenticationType) End If Dim userId As System.Security.Principal.IIdentity = HttpContext.Current.User.Identity ' If the roles aren't in cache, do it now. If System.Web.HttpContext.Current.Cache(userId.Name) Is Nothing Then ' Just a simple example using a dataset! Dim dsRoles As DataSet = SomeStaticClass.GetRoles(User.Identity.Name) ' Get roles as a comma delimited string Dim roles As String() = New String(dsRoles.Tables(0).Rows.Count - 1) {} For row As Integer = 0 To dsRoles.Tables(0).Rows.Count - 1 For col As Integer = 0 To dsRoles.Tables(0).Columns.Count - 1 roles(row) = dsRoles.Tables(0).Rows(row)(col).ToString() Next Next ' Usually this information will be collected from a database. ' One hour expiration time System.Web.HttpContext.Current.Cache.Add(userId.Name, roles, Nothing, DateTime.MaxValue, TimeSpan.FromHours(1), System.Web.Caching.CacheItemPriority.BelowNormal, _ Nothing) End If 'Assign the roles to the user in the current security context HttpContext.Current.User = New System.Security.Principal.GenericPrincipal(userId, DirectCast(System.Web.HttpContext.Current.Cache(userId.Name), String())) End If End If Catch ex As Exception Response.Redirect("/MyErrorPage") End Try