OK, bear with me on this because I've also got mixed into the bag the requirement to have mixed anonymous and NT authentication on the portal this code was written for. This is the custom object needed to extend the Context.User.Identity object (by the way,
I mistakenly said above the Context.User object inherits GenericIdentity - I meant the Context.User.Identity object): Public Class PortalIdentity Inherits GenericIdentity Private _employeeID As String Private _firstName As String Private _lastname As String
Private _roles As ArrayList Private _groupID As Integer Public Property LastName() As String Get Return _lastname End Get Set(ByVal Value As String) _lastname = Value End Set End Property Public Property GroupID() As Integer Get Return _groupID End Get Set(ByVal
Value As Integer) _groupID = Value End Set End Property Public Property EmployeeID() As String Get Return _employeeID End Get Set(ByVal Value As String) _employeeID = Value End Set End Property Public Property Roles() As ArrayList Get Return _roles End Get
Set(ByVal Value As ArrayList) _roles = Value End Set End Property Public ReadOnly Property FirstName() As String Get Return _firstName End Get End Property Public Sub New(ByVal name As String, ByVal FirstName As String) MyBase.New(name) _firstName = FirstName
End Sub Public Sub New(ByVal name As String, ByVal FirstName As String, ByVal type As String) MyBase.New(name, type) _firstName = FirstName End Sub End Class The other piece you must add is to manually serialize the object into the cookie (the FormsAuthentication
does this for you -- could possibly use the default FormsAuthentication routine to serialize and encrypt the cookie, but I haven't tested it since I am using NT authentication). The following function sends the cookie to the client if it does not already exist.
(again, this has a bit of tendency towards NT authentication - noted where applicable): Public Shared Sub SetUserIdentityCookie() ' Handles the single instance where a client is authenticating. ' The sender is the application context. We need to grab a reference
to it. Dim httpCon As HttpContext = HttpContext.Current Dim client As SqlDataReader ' Get roles from UserRoles table, and add to cookie Dim _user As New EmployeesDB() ' THIS LINE ASSUMES NT AUTHENTICATION. YOU WOULD OTHERWISE DO THE TYPICAL ' CHECK USING THE
LOGIN FORM AND VERIFYING THE CREDENTIALS ARE VALID. client = _user.GetSingleEmployeeByUserIdentity(httpCon.User.Identity.Name) ' DATA RETURNED FROM THE DATABASE ABOUT THIS CLIENT. COULD ALSO COMBINE ' THIS WITH THE STEP TO VALIDATE THE CLIENT. If client.Read()
Then 'Create an identity and serialize it to a cookie. - PASS IN THE NAME FROM THE ' DB, NOT httpCon.User.Identity.Name <- again, NT Authentication Dim ident As New PortalIdentity(httpCon.User.Identity.Name, client("first_name"), "CustomSecurity") ident.EmployeeID
= client("employee_id") ident.GroupID = client("group_id") ident.LastName = client("last_name") ident.Roles = _user.GetRoles(ident.EmployeeID) ' serialization objects Dim stream As New System.IO.MemoryStream() Dim format As New Formatters.Binary.BinaryFormatter()
Try ' Actually serialize format.Serialize(stream, ident) ' Declare a new cookie Dim cookie As New HttpCookie("portalsettings") cookie.Value = Convert.ToBase64String(stream.ToArray) ' Set cookie timeout cookie.Expires = Now.AddHours(8) httpCon.Response.Cookies.Add(cookie)
' Add our own custom principal to the request containing the roles httpCon.User = New GenericPrincipal(ident, ident.Roles.ToArray(GetType(String))) Catch ex As Exception ' Do nothing -- just don't authenticate End Try End If client.Close() End Sub The other
possibility is reading the cookie and reconstituting the custom identity object when a request comes in: If Not Request.Cookies("portalsettings") Is Nothing Then ' Reconstitute identity from cookie Dim ident As PortalIdentity Dim stream As New System.IO.MemoryStream()
Dim format As New Formatters.Binary.BinaryFormatter() Dim bytes() As Byte Try ' Get the byte array from the cookie bytes = Convert.FromBase64String(httpCon.Request.Cookies("portalsettings").Value) ' Write the byte array to a memory stream stream.Write(bytes,
0, UBound(bytes) + 1) ' Set the stream to the beginning and deserialize stream.Position = 0 ident = CType(format.Deserialize(stream), PortalIdentity) ' Add our own custom principal to the request containing the roles in the auth ticket httpCon.User = New GenericPrincipal(ident,
ident.Roles.ToArray(GetType(String))) Catch ex As Exception ' Do nothing End Try End If End Sub I created my own HTTPHandler to consolidate this functionality in one module, but you could just as easily replace the given code in the global.asax.vb file with
this code (probably needs minor tweaking, haven't done it myself). One thing to keep in mind is that the object now stored in Context.User.Identity might or might not be a PortalIdentity object (depending on whether the user has authenticated or not). So,
to make a call to one of the custom properties, you need to verify that you've got the correct object. For example, in my portaldesktopheader.ascx.vb file, to add personalization to the header, I've got: ' Personalize If TypeOf context.User.Identity Is PortalIdentity
Then WelcomeMessage.Text = "Welcome, " & CType(Context.User.Identity, PortalIdentity).FirstName & " |" WelcomeMessage.Visible = True hlLogout.Visible = True hlLogin.Visible = False End If Hope that was clear enough to point you in the right direction. =) David
davidbarrett
Member
155 Points
31 Posts
Re: Extending Context.User.Identity.Name to add USERID
Jan 13, 2003 06:14 PM|LINK