unable to retrieve the role in asp.net with MSSQL Server

62 Views Asked by At

I am working with asp.net and MSSQL server for development of online application, I like to add roles and Membership in website, membership and roles are stored in SQL Server, I tried and successes for login with SQL Users and while i change the code for restricted access for specific role the role is not listing on page. my code for page are like below:

For Login

        Dim userId As Integer = 0
        Dim roles As String = String.Empty
        Dim constr As String = ConfigurationManager.ConnectionStrings("InfinitudeConnectionString").ConnectionString
        Using con As New SqlConnection(constr)
            Using cmd As New SqlCommand("Validate_User")
                cmd.CommandType = CommandType.StoredProcedure
                cmd.Parameters.AddWithValue("@Username", Username.Text)
                cmd.Parameters.AddWithValue("@Password", Password.Text)
                cmd.Connection = con
                con.Open()
                Dim reader As SqlDataReader = cmd.ExecuteReader()
                reader.Read()
                userId = Convert.ToInt32(reader("UserId"))
                roles = reader("Roles").ToString()
                con.Close()
            End Using
            con.Close()
        End Using
        Select Case userId
            Case -1
                errorText.Visible = True
                errorText.Text = "Username and/or password is incorrect."
                Exit Select
            Case Else
                Dim ticket As New FormsAuthenticationTicket(1, Username.Text, DateTime.Now, DateTime.Now.AddMinutes(1), True, roles,
                FormsAuthentication.FormsCookiePath)
                Dim hash As String = FormsAuthentication.Encrypt(ticket)
                Dim cookie As New HttpCookie(FormsAuthentication.FormsCookieName, hash)
                If ticket.IsPersistent Then
                    cookie.Expires = ticket.Expiration
                End If
                Response.Cookies.Add(cookie)
                Session("login") = Username.Text
                Response.Redirect(FormsAuthentication.GetRedirectUrl(Username.Text, True))
                Exit Select
        End Select

After that Master Page for Code :

Page Load

         If Not Me.Page.User.Identity.IsAuthenticated Then
            Response.Redirect(FormsAuthentication.LoginUrl)
        ElseIf Session("login") = Nothing Then
            FormsAuthentication.SignOut()
            Session.Abandon()
            Session.RemoveAll()
            FormsAuthentication.RedirectToLoginPage("~/default")
        Else
            Using con As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("InfinitudeConnectionString").ConnectionString)
                Using cmd As SqlCommand = New SqlCommand
                    cmd.Connection = con
                    cmd.CommandType = CommandType.Text
                    cmd.CommandText = "select hashtable.Username, lastlogin, hashtable.HASHid, hashtable.compID, company_list.Company_Name from hashtable inner join company_list on company_list.CompanyID = hashtable.CompID where hashtable.username = '" + Session("login") + "'"
                    Dim dt As New DataTable()
                    con.Open()
                    Dim reader As SqlDataReader = cmd.ExecuteReader()
                    dt.Load(reader)
                    userID.Text = "Welcome Mr. " + dt.Rows(0).Item("Username").ToString.Trim()
                    LastLogin.Text = dt.Rows(0).Item("lastlogin").ToString.Trim()
                    Session("Companydetl") = dt.Rows(0).Item("compID").ToString.Trim()
                    Session("lastused") = dt.Rows(0).Item("HASHid").ToString.Trim()
                    con.Close()
                End Using
            End Using
        End If

Global.ASAX

Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
        If HttpContext.Current.User IsNot Nothing Then
            If HttpContext.Current.User.Identity.IsAuthenticated Then
                If TypeOf HttpContext.Current.User.Identity Is FormsIdentity Then
                    Dim id As FormsIdentity = DirectCast(HttpContext.Current.User.Identity, FormsIdentity)
                    Dim ticket As FormsAuthenticationTicket = id.Ticket
                    Dim userData As String = ticket.UserData
                    Dim roles As String() = userData.Split(",")
                    HttpContext.Current.User = New GenericPrincipal(id, roles)
                End If
            End If
        End If
    End Sub

when I run below code the menu is not visible.

<% if (HttpContext.Current.User.IsInRole("Atul")) Then %>
                <a href="/App/core/Company" title="Update Company Details"> Update Company Details</a>
                <% end if %>

and when I try to know the role of the current user it display blank.

please help

1

There are 1 best solutions below

5
Albert D. Kallal On

First up, you should always use parameters WHEN dealing with user input. You can get away using string concatenation for internal code, but when input comes from the web page, you REALLY want to use parameters.

So, for example, your code snip should be this:

Also, note that a sql command object has a connection, has a reader. So LITTLE need to code over and over a seperate conneciton object and a reader - you do NOT need those - they eixst as part of the sqlcommand object.

eg this:

    Dim strSQL As String
    strSQL = "select hashtable.Username, lastlogin, hashtable.HASHid, hashtable.compID, company_list.Company_Name from hashtable " &
           "inner join company_list on company_list.CompanyID = hashtable.CompID " &
           "WHERE hashtable.username = @Login"

    Using cmd As SqlCommand = New SqlCommand(strSQL,
                      New SqlConnection(ConfigurationManager.ConnectionStrings("InfinitudeConnectionString").ConnectionString))

        cmd.Parameters.Add("@Login", SqlDbType.NVarChar).Value = Session("login")

        Dim dt As New DataTable()
        cmd.Connection.Open()
        dt.Load(cmd.ExecuteReader)
        With dt.Rows(0)
            userID.Text = "Welcome Mr. " + .Item("Username")
            LastLogin.Text = .Item("lastlogin")
            Session("Companydetl") = .Item("compID")
            Session("lastused") = .Item("HASHid")
        End With

    End Using

So, note how I don't need a separate connection object, and I don't need a reader (they already exist as part of the sql command object. So, just trying to save your keyboard here!!

Next up:

To test/check for role membership? If you setup security tables correctly, then you should have something like this:

enter image description here

You REALLY want to ensure that your tables follow the standard asp.net security.

Now in above, my main contact table is custom, but the rest of the tables are the standard ones required and generated by running the sql scripts to setup security. The REASON why this is a HUGE deal? Then you can secuire ANY web page by simply dropping in and haveing a web.config file in any sub folder, and thus you can secure any web page AUTOMATIC without code based on the users role.

So, you can say use this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>

    <authorization>
            <allow roles="PortalMaster" />
        <deny users="*" />
        </authorization>
    </system.web>
</configuration>

So now, any user to use any page in that sub folder with the above web config? They MUST be a member of PortalMaster - they can't even load that page if they try to - no code required.

And if you done this correct, to test for role membership, then you can and should use this:

  If Roles.IsUserInRole("PortalMaster") then
      ' code goes here for user role = PortalMaster
  End if

So you can and should be able to use Roles.IsUserInRole("some role name")

Dim roles As String() = userData.Split(",")

Above is a bad idea - the roles need to come from the Web_usersInRoles table.

If you need to display all roles for a given user, then you can do this:

Say we have a simple button + text box:

   <br />
    <asp:Button ID="Button1" runat="server" Height="34px" Text="Button" Width="170px" />
    <br />
    <asp:TextBox ID="TextBox1" runat="server" Height="188px" TextMode="MultiLine" Width="423px"></asp:TextBox>

The button code can be this:

   For Each MyRole As String In Roles.GetRolesForUser()
        TextBox1.Text &= MyRole & vbCrLf
    Next

result:

enter image description here

And with this setup, then in say the master page, you can control/set/hide menu bar items like this:

<li id="mAdmin" runat="server" class="dropdown"  ClientIDMode="Static">

so above is a menu bar - master page. With roles, we can now do this:

 Me.mAdmin.Visible = Roles.IsUserInRole("SiteAdmin")

So, to run security on that site - you really - but really really really want to use and have the membership role tables setup correctly here.

So to test for membership in a role you can and should be able to use

Roles.IsUserInRole("some role name here") = true/false