So ive got my login page almost completed, now for whatever reason i am stuck trying to get the roles for each user from my database into the authorization cookie. In regular old asp this wouldn't be a problem for me, but don't see what im doing wrong in .net

so you can see where i create my ticket, and i hard coded Admin in there, and tested that to make sure everything works, and since it does i need it to be dynamic so when a regular user logs in they will only have user rights.

Here is the code to my login page

<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Threading" %>

<script runat="server">
    Dim conMyData As SqlConnection
    Dim conUserData As SqlConnection
    Dim cmdSelect As SqlCommand
    Dim cmdSelectRoles As SqlCommand
    Dim parmReturnValue As SqlParameter
    Dim intResult As Integer
    Dim strLinkPath As String
    Dim objTicket As FormsAuthenticationTicket
    Dim objCookie As HttpCookie
    Dim strReturnURL As String

    Sub Button_Click(ByVal a As Object, ByVal e As EventArgs)
        If IsValid Then
            'load stored procedure DBAuthenticate
            If DBAuthenticate(txtUsername.Text, txtPassword.Text) > 0 Then
                'create authentication ticket
                objTicket = New FormsAuthenticationTicket(2, txtUsername.Text, DateTime.Now, DateTime.Now.AddMinutes(30), False, "Admin")
                'create cookie UserName
                Response.Cookies("UserName").Value = txtUsername.Text
                objCookie = New HttpCookie(".ASPXAUTH")
                objCookie.Value = FormsAuthentication.Encrypt(objTicket)
                Response.Cookies.Add(objCookie)
                strReturnURL = Request.Params("ReturnURL")
                If strReturnURL <> Nothing Then
                    'returns user to previous page if greater authorization was required
                    Response.Redirect(strReturnURL)
                Else
                    'forwards user after logi
                    Response.Redirect("role_page.aspx")
                End If
            End If
        End If
    End Sub
    
    'check failed login attempt count and if greater than 3 pauses for 2 hours
    Sub Page_Load()
        Dim objCounter As Object = Session("counter")
        If Session("counter") > 3 Then
            thread.sleep(7200000)
            Response.Redirect("deny.aspx")
        End If
    End Sub
    
    'stored procedure, returns 1 if successful login, -1 it not
    Function DBAuthenticate(ByVal strUsername As String, ByVal strPassword As String) As Integer
        conMyData = New SqlConnection("Server=INTRANET;UID=sa;Database=safety_training")
        cmdSelect = New SqlCommand("DBAuthenticate", conMyData)
        cmdSelect.CommandType = CommandType.StoredProcedure
        parmReturnValue = cmdSelect.Parameters.Add("RETURN_VALUE", SqlDbType.Int)
        parmReturnValue.Direction = ParameterDirection.ReturnValue
        cmdSelect.Parameters.AddWithValue("@Username", strUsername)
        cmdSelect.Parameters.AddWithValue("@Password", strPassword)
        conMyData.Open()
        cmdSelect.ExecuteNonQuery()
        intResult = cmdSelect.Parameters("RETURN_VALUE").Value
        conMyData.Close()
        'if unsuccessful login display message and increase failed attempt count by 1 then
        'pauses for 10, then 20, then 30 seconds if user keeps failign
        If intResult = -1 Then
            lblMessage.Text = "Your Username or Password is incorrect.  Please try again."
            Dim objCounter As Object = Session("counter")
            If objCounter Is Nothing Then objCounter = 0
            Session("counter") = CInt(objCounter) + 1
            Thread.Sleep(10000 * (CInt(objCounter)))
        End If
        Return intResult
    End Function
    
</script>

<html>
<head><title>Login.aspx</title></head>
<body style="text-align: center">
<form id="Form1" runat="server">
    &nbsp;<table style="width: 264px; height: 155px;">
        <tr>
            <td colspan="2" style="height: 43px; text-align: center">
                <strong><span style="font-size: 16pt">
                Please Login:</span></strong></td>
        </tr>
        <tr>
            <td colspan="2" style="text-align: center">

<asp:Label
    ID="lblMessage"
    ForeColor="Red"
    Font-Bold="true"
    Runat="server" /></td>
        </tr>
        <tr>
            <td style="width: 60px">
                <strong>Username:</strong></td>
            <td style="width: 11px">
<asp:TextBox
    ID="txtUsername"
    Runat="server" Width="160px" /></td>
        </tr>
        <tr>
            <td colspan="2" style="height: 1px">
            </td>
        </tr>
        <tr>
            <td style="width: 60px">
                <strong>Password:</strong></td>
            <td style="width: 11px">
<asp:TextBox
    ID="txtPassword"
    Runat="server" TextMode="Password" Width="160px" /></td>
        </tr>
        <tr>
            <td colspan="2" style="text-align: right">
<asp:Button
    Text="Login"
    OnClick="Button_Click"
    Runat="server" ID="Button1" /></td>
        </tr>
    </table>
<hr>
</form>
</body>
</html>

Dani AI

Generated

Good job and thanks to for the direction. The piece that commonly trips people up after putting roles into the auth ticket is rebuilding the user principal on every request so ASP.NET role checks actually work. Below is a focused, practical checklist and a small VB example to fill that gap plus a few safety notes you won't find in the original posts.

  • At login: collect the user's roles (allow for multiple), join them into a short, comma‑separated string and put that string into the FormsAuthenticationTicket.UserData before encrypting the cookie. Ensure the cookie is marked HttpOnly and Secure when using HTTPS.
  • On every request: implement Application_AuthenticateRequest in Global.asax to decrypt the ticket, split UserData into a roles array and set Context.User (and Thread.CurrentPrincipal) to a GenericPrincipal built from the ticket identity and roles. This makes User.IsInRole and configuration-based <authorization> work site-wide.

Example (Global.asax.vb):

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
    Dim authCookie = Context.Request.Cookies(FormsAuthentication.FormsCookieName)
    If authCookie Is Nothing Then Return

    Dim ticket = FormsAuthentication.Decrypt(authCookie.Value)
    If ticket Is Nothing Then Return

    Dim roles() As String = If(String.IsNullOrEmpty(ticket.UserData), New String() {}, ticket.UserData.Split(","c))
    Dim id = New FormsIdentity(ticket)
    Dim principal = New System.Security.Principal.GenericPrincipal(id, roles)
    Context.User = principal
    Thread.CurrentPrincipal = principal
End Sub

Security and reliability notes:

  • Never use the SQL Server sa account or store plaintext passwords; store salted hashes and validate server-side.
  • Do not use Thread.Sleep on the server to throttle failed logins — that ties up worker threads. Track failures (DB or cache) and lock or rate‑limit accounts/IPs instead.
  • If you run a web farm, sync machineKey so your tickets decrypt on every node.
  • For new projects consider built-in providers (ASP.NET Membership/RoleProvider) or modern Identity frameworks instead of manual cookie payloads.

Troubleshooting: if role checks fail, confirm the cookie exists, the ticket decrypts, UserData contains the expected CSV, and that the Global.asax handler is firing (check authentication mode and pipeline).

Recommended Answers

All 4 Replies

Have you tried creating a function that makes a call to the DB 'where UserName = ' & txtUserName.Text and return that value to a string variable you pass into the authentication.ticket method?

yes, it works with "Admin" hard coded in there, but i am new to .net and still learning everything. Looking at that code, I don't know how to get my stored proceedure to return the users role. I tried writing another one, but it didn't work out to well. I guess this just comes down to writing a query and converting the results to a string and then inserting them into that ticket.

Thanks for at least trying to help, but some of the people at helped me out after i took your advice.

Here is the code that made it all work for me. This goes in the login page;

Sub Button_Click(ByVal a As Object, ByVal e As EventArgs)
        If IsValid Then
            'load stored procedure DBAuthenticate
            If DBAuthenticate(txtUsername.Text, txtPassword.Text) > 0 Then
                [B]Dim conRoles As SqlConnection
                Dim cmdSelectRoles As SqlCommand
                Dim dtrRoles As String

                conRoles = New SqlConnection("Server=INTRANET;uid=sa;database=safety_training")
                conRoles.Open()
                cmdSelectRoles = New SqlCommand("SELECT g.name FROM dbo.Groups g WHERE g.group_id IN (SELECT r.group_id FROM dbo.Roles r WHERE r.user_id IN (SELECT ui.user_id FROM dbo.User_Info ui WHERE ui.user_name=@username AND ui.password=@password))", conRoles)
                cmdSelectRoles.Parameters.AddWithValue("@username", txtUsername.Text)
                cmdSelectRoles.Parameters.AddWithValue("@password", txtPassword.Text)
                dtrRoles = cmdSelectRoles.ExecuteScalar[/B]

                'create authentication ticket
                objTicket = New FormsAuthenticationTicket(2, txtUsername.Text, DateTime.Now, DateTime.Now.AddMinutes(30), False, dtrRoles)
                [B]conRoles.Close()[/B]

Now since I don't know how to get this page to redirect depending on the role of the user, I redirected to another page and had that page check the role of the user and then they are redirected to the page i want them to start out at.

Good work.

Just an FYI (understanding .NET, doesn't excuse from needing an understanding of SQL)

pseudo-code

CREATE PROCEDURE sp_GetRole /* How it would appear in QUERY ANALYZER */
	(
		@UserName VARCHAR(50) = NULL,
		@Password VARCHAR(50) = NULL,
		@Role VARCHAR(20) = NULL 
	)
AS
	SET @Role = (SELECT Role
	FROM UserTable /* or what you called you table with this data */
	WHERE UserName = @UserName AND Password = @Password)
RETURN @Role

Hope this helps!

Glad to see you found another option.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.