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 |
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
|
|
|
| |
|
| |
| |
| Jim Ross [MVP] (VIP) |
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
|
|
|
| |
|
|
| |
|
|
|
|
|