首页 > 解决方案 > 无法使用 MSSQL Server 在 asp.net 中检索角色

问题描述

我正在使用 asp.net 和 MSSQL 服务器开发在线应用程序,我喜欢在网站中添加角色和成员资格,成员资格和角色存储在 SQL Server 中,我尝试使用 SQL 用户登录并成功,同时我更改了代码对于特定角色的受限访问,该角色未在页面上列出。我的页面代码如下:

登录

        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

在代码母版页之后:

页面加载

         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

全球.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

当我在代码下方运行时,菜单不可见。

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

当我尝试了解当前用户的角色时,它显示为空白。

请帮忙

标签: asp.netsql-serverasp.net-membershiproles

解决方案


首先,在处理用户输入时,您应该始终使用参数。您可以对内部代码使用字符串连接,但是当输入来自网页时,您真的想使用参数。

因此,例如,您的代码片段应该是这样的:

另外,请注意,一个 sql 命令对象有一个连接,有一个阅读器。所以很少需要对一个单独的连接对象和一个阅读器进行一遍又一遍的编码——你不需要那些——它们作为 sqlcommand 对象的一部分。

例如这个:

    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

所以,请注意我不需要单独的连接对象,也不需要阅读器(它们已经作为 sql 命令对象的一部分存在。所以,只是想把你的键盘保存在这里!!

接下来:

测试/检查角色成员资格?如果你正确设置了安全表,那么你应该有这样的东西:

在此处输入图像描述

您真的希望确保您的表遵循标准的 asp.net 安全性。

现在在上面,我的主要联系人表是自定义的,但其余表是通过运行 sql 脚本来设置安全性所需和生成的标准表。这是一笔巨额交易的原因?然后,您可以通过简单地放入并在任何子文件夹中拥有一个 web.config 文件来保护任何网页,因此您可以根据用户角色在没有代码的情况下自动保护任何网页。

所以,你可以说使用这个:

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

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

那么现在,任何用户都可以通过上述网络配置使用该子文件夹中的任何页面吗?他们必须是 PortalMaster 的成员 - 如果他们尝试加载,他们甚至无法加载该页面 - 不需要代码。

如果你做对了,为了测试角色成员资格,那么你可以并且应该使用这个:

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

所以你可以而且应该能够使用 Roles.IsUserInRole("some role name")

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

上面是一个坏主意 - 角色需要来自 Web_usersInRoles 表。

如果您需要显示给定用户的所有角色,那么您可以这样做:

假设我们有一个简单的按钮 + 文本框:

   <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>

按钮代码可以是这样的:

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

结果:

在此处输入图像描述

使用此设置,然后在母版页中,您可以控制/设置/隐藏菜单栏项,如下所示:

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

所以上面是一个菜单栏 - 母版页。有了角色,我们现在可以这样做:

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

因此,要在该站点上运行安全性——你真的——但真的真的很想在这里使用并正确设置成员角色表。

因此,要测试角色的成员资格,您可以并且应该能够使用

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

推荐阅读