【问题标题】:unable to retrieve the role in asp.net with MSSQL Server无法使用 MSSQL Server 在 asp.net 中检索角色
【发布时间】:2021-08-03 18:19:41
【问题描述】:

我正在使用 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.net sql-server asp.net-membership roles


    【解决方案1】:

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

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

    另外,请注意,一个 sql 命令对象有一个连接,有一个阅读器。 所以 LITTLE 需要一遍又一遍地编写一个单独的连接对象和一个阅读器——你不需要那些——它们作为 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
    

    【讨论】:

    • 我尝试了您的解决方案,但它在 getrolesforuser() 中显示为 null
    • 您是否创建了 sql server 角色和成员船表?假设您为正在使用的给定数据库设置了 SQL 服务器安全设置。假设说 .net 4.0 或更高版本,那么您必须运行此实用程序来为您创建 sql 安全表。你做过吗? --- 这个:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regsql.exe ---- 这会启动一个向导来为您创建安全表?
    • 您必须提供更多信息,以及您尝试过哪些没有奏效。现在看来,您甚至没有基本的登录工作。如果没有基本的登录工作,那么询问角色就太高级了,太超前了。因此,如果您没有基本的登录工作,那么您就不能询问角色。我将提出一个关于如何使登录正常工作的新问题。只有在您有基本的登录工作之后,您才能开始询问有关角色和此类角色的成员资格的问题。
    • sql server中的自定义表是否可以一样
    • 您必须将角色提供者指向这些表,并且它们应该与 ER 图具有相同的结构。如果表结构与 ER 图不同,那么您必须构建一个自定义角色提供者(继承内置的)。你真的很想使用内置的安全性,因为那时网页可以通过角色成员资格来保护,这可以在你没有任何代码的情况下完成。 (因此“SalesGroup”的某些网页只能由 Role=SalesGroup 使用)您可以使用内置安全模型的越多,您需要编写的代码就越少。即使忘记密码选项也可以在不编写任何代码的情况下工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 2018-09-18
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    相关资源
    最近更新 更多