Multimobile Development: Building Applications for any Smartphone
ASP.NET Forms Authentication with users/roles stored in db
Messages   Related Types
This message was discovered on microsoft.public.dotnet.framework.aspnet.security.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.

Michael Iantosca
GOOD ANSWER
I am trying to implement forms based authentication where
I look up a username and password in a database to see if
they should be authenticated. Once they are - I want to
persist their roles as long as they are logged in so I
can easily check to see if the currect user requesting a
page is in a particular role or not.

The login part works fine but when I try to use a generic
identity and principle to add the user's role(s) - as
soon as I redirect to the requested page the identity
object looks like it has been reset because the roles are
no longer set.

How can I get the roles to persist across page requests -
I attached the generic prinicple object to the current
httpcontext but the IsInRole call always returns false.
The Identity.Name and Identity.Authenticated values
remain in tact though

any help?
Michael
Reply to this message...
Vote that this is a GOOD answer... (1 vote from another user already)
 
 
    
Jim Ross [MVP] (VIP)
GOOD ANSWER
You have to put the role into the authentication "ticket".

There are a couple of pieces to it, at least the way I did it. I used
the "UserData" portion of the FormsAuthenticationTicket to save the
role from the database at Login, then I retrieve the role in the
AuthenticateRequest handler in global.asax

Here is the code in global.asax. Note that the "role" is actually an
array of roles, so a user can be in more than one role. It is actually
pretty simple.

Sub Application_AuthenticateRequest(_
    ByVal sender As Object, ByVal e As EventArgs)
' Fires upon attempting to authenticate the use

' set the user role '
        ' this was set during login processing (login.aspx.vb)
if Context.Request.IsAuthenticated then
     Dim arrRoles as String()
         Dim ident as System.Web.Security.FormsIdentity
            ident = Context.User.Identity
            arrRoles = ident.Ticket.UserData.Split(",")
            Context.User = New GenericPrincipal(ident, arrRoles)
        End If
End Sub

The harder part is setting the UserData at login. You have to do a
custom Authentication Cookie. Here is that code: [I pulled out the
database access part to keep this simple]

Private Sub cmdLogin_Click(_
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
        Handles cmdLogin.Click

    Dim authTkt as FormsAuthenticationTicket
    Dim authCookie as HttpCookie
    Dim retURL as String
    
    If Not IsValid Then
        Return
    End If    
        
    ' page that called us. we will be returning there if
    ' login succeeds (have to do it yourself with the technique
    ' used here to build our own authentication ticket)
    retURL = Request.Params("ReturnURL")
    if retURL = Nothing then
        retURL = "index.aspx"
    End If        
            
    ' try to lookup the entered ID and validate its password
    cmdSelectPerson.Parameters("@UserID").Value = _
                                     Trim(txtUserID.Text)
    try
        ' do your database stuff here
    catch excp as SqlException
        ' handle any dataaccess stuff here
    end try
    
    ' verify the login here

    ' database has a unique constraint index on UserID, so
    ' database will return either one or none
    if dsPerson.Tables("Persons").Rows.Count = 0 Then
        lblMessage.Text = "Bad User ID or Password"
        Return
    End If    
    dr = dsPerson.Tables("Persons").Rows(0)
    if dr.Password <> Trim(txtPassword.Text) then
        lblMessage.Text = "Bad User ID or Password"
        Return                        
    End If
        
    ' id and password are ok.
    ' Set the credentials cookie and return
        
    ' build a friendly copy of their name
    ' TODO: get in the habit of using a stringbuilder
    '        instead of this
    Dim strName as String
    strName = Trim(dr.FirstName) + " "
    if Len(Trim(dr.MiddleInitial)) > 0 then
        strName = strName + dr.MiddleInitial + ". "
    end if
    strName = strName + Trim(dr.LastName)
    ' store the user id in the name so that
    ' we can easily extract it when updating the database
    strName = strName + "#" + dr.PersonID.ToString
        
    ' if we add a "remember me" option later,
    ' we'll check that to set this value
    ' for now, just default to "false"
    ' so that the authentiction will expire with the session
    Dim bRemember as Boolean
    bRemember = False
    
    ' build the authentication ticket
    authTkt = New FormsAuthenticationTicket( 1, _
            strName, _
            Now(), _
            Now().AddDays(1), _
            bRemember, _
            Trim(dr.UserType))
    ' use the ticket to issue the authentication cookie
    authCookie = new HttpCookie(FormsAuthentication.FormsCookieName)
    authCookie.Value = FormsAuthentication.Encrypt(authTkt)
    Response.Cookies.Add(authCookie)
            
    ' send the user back to the page they requested
    Response.Redirect(retURL)
        
End Sub

Note that you had to do your own redirect instead of relying on
FormsAuthentication's automatic one. That's because of building the
custom ticket.

This is running fine for me in my app--so far. It took about an hour
to copy out of a book (Steven Walther's "ASP.NET Unleashed" and adapt
to my app. It would probably have taken a day or two if I had had to
dig it out of the docs for myself. Hope this helps,

"Michael Iantosca" <Click here to reveal e-mail address> wrote:

[Original message clipped]

Jim Ross
MS MVP [ASP.NET][VC/MFC emeritus]

To send email, change 'lotsofspamthroughhere' to 'msn' but please ask all questions in the newsgroups, not via private mail
Reply to this message...
Vote that this is a GOOD answer... (1 vote from another user already)
 
 
 
System.Data.SqlClient.SqlException
System.EventArgs
System.Object
System.Runtime.Remoting.Contexts.Context
System.Security.Principal.GenericPrincipal
System.Web.HttpCookie
System.Web.Security.FormsAuthentication
System.Web.Security.FormsAuthenticationTicket
System.Web.Security.FormsIdentity




Multimobile Development: Building Applications for any Smartphone
Ad
BootFX
Reliable and powerful .NET application framework.
iOS, Android and Windows Phone Development Training and Consultancy
Hosted by RackSRV Communications
 
Multimobile Development: Building Applications for any Smartphone
Copyright © AMX Software Ltd 2008-2010. Portions copyright © Matthew Baxter-Reynolds 2001-2010. All rights reserved.
Contact Us - Terms of Use - Privacy Policy - 4.0.30129.1734