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
