J
Jakob Lithner
I am new to ASP.Net Forms Authentication but read the newsgroup thorughly.
Goals:
I want to allow anonymous users but allow more functionality for logged in
users depending on roles.
I want to store a specific database ID in the ticket to make lookups easier.
From different messages I got most of the idea and thought I came up with a
pretty good setup. It works as expected as long as the browser session lives.
The problem is the cookie is never saved to the browser, as far as I can see
(Internet Options - General - Settings - View Files). When the browser is
closed (or when I enter another browser) the authentication is gone.
I am almost there but some little detail must be missing.
Any help is very appreciated!
web.config
=========================================
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
defaultUrl="Default.aspx"
name=".ASPXFORMSAUTH"
path="\">
</forms>
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
Login.aspx
=========================================
Partial Class Login
Inherits System.Web.UI.Page
Protected Sub cmdLogin_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdLogin.Click
Dim New DatabaseUser(txtUserID.Text, txtPassword.Text)
'Creates a preformatted string on the form: "PersonID;Role1,Role2,Role3"
i.e. "54;Admin,User"
Dim userData As String = DatabaseUser.UserData
Dim authTicket As FormsAuthenticationTicket
If DatabaseUser.IsValidated Then
authTicket = New FormsAuthenticationTicket(1, txtUserID.Text,
DateTime.Now, DateTime.Now.AddMinutes(60), chkPersist.Checked, userData)
'Encrypt the ticket.
Dim encTicket As String = FormsAuthentication.Encrypt(authTicket)
'Create the cookie.
Dim cookie As HttpCookie = New
HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
'Save the cookie
Response.Cookies.Add(cookie)
If Request.QueryString("ReturnUrl") = Nothing Then
'Redirect to default page
Response.Redirect(FormsAuthentication.DefaultUrl)
Else
'Redirect to requested page
Response.Redirect(Request.QueryString("ReturnUrl"))
'Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUserID.Text,
chkPersist.Checked))
'FormsAuthentication.RedirectFromLoginPage(txtUserID.Text,
chkPersist.Checked)
End If
Else
lblFailure.Text = "Login failed. Please check your user name and
password and try again."
End If
End Sub
End Class
CustomPrincipal
========================================
Public Class CustomPrincipal
Inherits System.Security.Principal.GenericPrincipal
Private m_PersonID As Integer
Public Sub New(ByVal identity As System.Security.Principal.IIdentity,
ByVal PersonID As Integer, ByVal roles As String())
MyBase.New(identity, roles)
m_PersonID = PersonID
End Sub
Public ReadOnly Property PersonID() As Integer
Get
Return m_PersonID
End Get
End Property
End Class
global.asax
=========================================
Protected Sub Application_AuthenticateRequest(ByVal sender As Object,
ByVal e As System.EventArgs)
Dim app As HttpApplication
Dim authTicket As FormsAuthenticationTicket
Dim authCookie As String = ""
Dim cookieName As String = FormsAuthentication.FormsCookieName
Dim userIdentity As FormsIdentity
Dim userData As String
Dim userDataGroups As String()
Dim PersonID As Integer
Dim roles As String()
Dim userPrincipal As CustomPrincipal
app = DirectCast(sender, HttpApplication)
If app.Request.IsAuthenticated AndAlso
app.User.Identity.AuthenticationType = "Forms" Then
Try
'Get authentication cookie
authCookie = app.Request.Cookies(cookieName).Value
Catch ex As Exception
'Cookie not found generates exception: Redirect to loginpage
Response.Redirect("Login.aspx")
End Try
'Decrypt the authentication ticket
authTicket = FormsAuthentication.Decrypt(authCookie)
'Create the identity
userIdentity = New FormsIdentity(authTicket)
'Retrieve the user data from the ticket
userData = authTicket.UserData
'Split user data in main sections
userDataGroups = userData.Split(";"c)
'Read out ID and roles
PersonID = CType(userDataGroups(0), Integer)
roles = userDataGroups(1).Split(","c)
'Rebuild the principal
userPrincipal = New CustomPrincipal(userIdentity, PersonID, roles)
'Set the principal as the current user identity
app.Context.User = userPrincipal
End If
End Sub
Goals:
I want to allow anonymous users but allow more functionality for logged in
users depending on roles.
I want to store a specific database ID in the ticket to make lookups easier.
From different messages I got most of the idea and thought I came up with a
pretty good setup. It works as expected as long as the browser session lives.
The problem is the cookie is never saved to the browser, as far as I can see
(Internet Options - General - Settings - View Files). When the browser is
closed (or when I enter another browser) the authentication is gone.
I am almost there but some little detail must be missing.
Any help is very appreciated!
web.config
=========================================
<authentication mode="Forms">
<forms loginUrl="Login.aspx"
defaultUrl="Default.aspx"
name=".ASPXFORMSAUTH"
path="\">
</forms>
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
Login.aspx
=========================================
Partial Class Login
Inherits System.Web.UI.Page
Protected Sub cmdLogin_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cmdLogin.Click
Dim New DatabaseUser(txtUserID.Text, txtPassword.Text)
'Creates a preformatted string on the form: "PersonID;Role1,Role2,Role3"
i.e. "54;Admin,User"
Dim userData As String = DatabaseUser.UserData
Dim authTicket As FormsAuthenticationTicket
If DatabaseUser.IsValidated Then
authTicket = New FormsAuthenticationTicket(1, txtUserID.Text,
DateTime.Now, DateTime.Now.AddMinutes(60), chkPersist.Checked, userData)
'Encrypt the ticket.
Dim encTicket As String = FormsAuthentication.Encrypt(authTicket)
'Create the cookie.
Dim cookie As HttpCookie = New
HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
'Save the cookie
Response.Cookies.Add(cookie)
If Request.QueryString("ReturnUrl") = Nothing Then
'Redirect to default page
Response.Redirect(FormsAuthentication.DefaultUrl)
Else
'Redirect to requested page
Response.Redirect(Request.QueryString("ReturnUrl"))
'Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUserID.Text,
chkPersist.Checked))
'FormsAuthentication.RedirectFromLoginPage(txtUserID.Text,
chkPersist.Checked)
End If
Else
lblFailure.Text = "Login failed. Please check your user name and
password and try again."
End If
End Sub
End Class
CustomPrincipal
========================================
Public Class CustomPrincipal
Inherits System.Security.Principal.GenericPrincipal
Private m_PersonID As Integer
Public Sub New(ByVal identity As System.Security.Principal.IIdentity,
ByVal PersonID As Integer, ByVal roles As String())
MyBase.New(identity, roles)
m_PersonID = PersonID
End Sub
Public ReadOnly Property PersonID() As Integer
Get
Return m_PersonID
End Get
End Property
End Class
global.asax
=========================================
Protected Sub Application_AuthenticateRequest(ByVal sender As Object,
ByVal e As System.EventArgs)
Dim app As HttpApplication
Dim authTicket As FormsAuthenticationTicket
Dim authCookie As String = ""
Dim cookieName As String = FormsAuthentication.FormsCookieName
Dim userIdentity As FormsIdentity
Dim userData As String
Dim userDataGroups As String()
Dim PersonID As Integer
Dim roles As String()
Dim userPrincipal As CustomPrincipal
app = DirectCast(sender, HttpApplication)
If app.Request.IsAuthenticated AndAlso
app.User.Identity.AuthenticationType = "Forms" Then
Try
'Get authentication cookie
authCookie = app.Request.Cookies(cookieName).Value
Catch ex As Exception
'Cookie not found generates exception: Redirect to loginpage
Response.Redirect("Login.aspx")
End Try
'Decrypt the authentication ticket
authTicket = FormsAuthentication.Decrypt(authCookie)
'Create the identity
userIdentity = New FormsIdentity(authTicket)
'Retrieve the user data from the ticket
userData = authTicket.UserData
'Split user data in main sections
userDataGroups = userData.Split(";"c)
'Read out ID and roles
PersonID = CType(userDataGroups(0), Integer)
roles = userDataGroups(1).Split(","c)
'Rebuild the principal
userPrincipal = New CustomPrincipal(userIdentity, PersonID, roles)
'Set the principal as the current user identity
app.Context.User = userPrincipal
End If
End Sub