-3

我的登录系统有问题,并在使用第一个用户(管理员)时寻求一些极客帮助,系统会做它需要做的事情。但是当我尝试使用其他用户登录时,它将无法正常工作。我得到了我的错误username and password unknown,当我从代码中删除以下行时,我可以与所有其他用户一起登录,

   ElseIf (currentUser <> username AndAlso currentPassword <> password) Then
      MessageBox.Show("Username and password unknown", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return False

源代码,

Public Function Login(ByVal username As String, ByVal password As String)
    Dim usersDatasSet As New DataSet()
    usersDataAdapter.FillSchema(usersDatasSet, SchemaType.Source, "Users")
    usersDataAdapter.Fill(usersDatasSet, "Users")
    Dim table As DataTable = usersDatasSet.Tables("Users")

    For i As Integer = 0 To table.Rows.Count - 1
        Dim currentUser As String = table.Rows(i)("Username").ToString().Trim()
        Dim currentPassword As String = table.Rows(i)("Password").ToString().Trim()


        'Check input

        If (currentUser <> username And currentPassword = password) Then
            MessageBox.Show("Unknown user", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return False

        ElseIf (currentUser = username And currentPassword <> password) Then
            MessageBox.Show("Wrong password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return False


        ElseIf (currentUser <> username AndAlso currentPassword <> password) Then
            MessageBox.Show("Username and  password unknown", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return False

        ElseIf (currentUser = username AndAlso currentPassword = password) Then
            usersDatasSet.Dispose()
            Connection.Close()
            Return True
        End If

    Next
    usersDatasSet.Dispose()
    Connection.Close()
    Return False
End Function

感谢您在此问题上的任何帮助。

4

1 回答 1

2

您正在遍历表中的行,根据用户提供的 UserName 和 Password 值检查每一行的值。

由于您的第一个用户是管理员,管理员将始终能够登录。

由于您的ElseIf (currentUser <> username AndAlso currentPassword <> password) Then阻止,任何其他用户都会失败(您尝试使用 John 登录,但您使用的是管理员的凭据)。

当您删除ElseIf (currentUser <> username AndAlso currentPassword <> password) Then任何用户都可以登录时 - 因为他们实际上是以管理员身份登录的。

尝试从表中选择用户并将用户名和密码与提供的值进行比较。

你应该做什么

为了验证用户是否可以登录,您可以执行以下操作(而不是您的 For 循环):

Public Function Login(ByVal username As String, ByVal password As String) As Boolean

    ' Set a flag for whether or not login was successful
    Dim LoggedIn As Boolean = False
    Dim usersDatasSet As New DataSet()
    usersDataAdapter.FillSchema(usersDatasSet, SchemaType.Source, "Users")
    usersDataAdapter.Fill(usersDatasSet, "Users")
    Dim table As DataTable = usersDatasSet.Tables("Users")

    ' This will return an array of DataRows that have the specified
    ' username in them.
    ' You will need to have unique usernames for this to work
    Dim credentials() As DataRow = table.Select("Username = '" + username + "'")

    If (credentials.Length = 1) Then
        Dim currentUser As String = credentials(0)("Username").ToString()
        Dim currentPassword As String = credentials(0)("Password").ToString()

        If (currentUser <> username And currentPassword = password) Then
            MessageBox.Show("Unknown user", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        ElseIf (currentUser = username And currentPassword <> password) Then
            MessageBox.Show("Wrong password", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        ElseIf (currentUser <> username AndAlso currentPassword <> password) Then
            MessageBox.Show("Username and  password unknown", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        ElseIf (currentUser = username AndAlso currentPassword = password) Then
            LoggedIn = True
        End If
    Else
        MessageBox.Show("Mulitple users found for " & username, "Error", MessageBox.Buttons.OK, MessageBox.Icon.Error)
    End If

    usersDatasSet.Dispose()
    Connection.Close()

    Return LoggedIn
End Function

这将允许您告诉用户是否是未通过验证的用户名或密码,并处理您是否有多个用户具有相同的用户名。

然而

我不鼓励您使用这样的系统(告诉用户登录的哪个部分失败),因为如果黑客尝试暴力攻击,它可能会向他们提供信息。(是的,我知道,这里可能有点过于偏执了)。

最好像这样简化它:

Public Function Login(ByVal username As String, ByVal password As String) As Boolean

    ' Set a flag for whether or not login was successful
    Dim LoggedIn As Boolean = False
    Dim usersDatasSet As New DataSet()
    usersDataAdapter.FillSchema(usersDatasSet, SchemaType.Source, "Users")
    usersDataAdapter.Fill(usersDatasSet, "Users")
    Dim table As DataTable = usersDatasSet.Tables("Users")

    ' This will return an array of DataRows that have the specified
    ' username in them.
    ' You will need to have unique usernames for this to work
    Dim credentials() As DataRow = table.Select("Username = '" + username + "' AND Password = '" + password + "'")

    If (credentials.Length =1 ) Then
        LoggedIn = True
    Else
        MessageBox.Show("Invalid username/password combination", "Error", MessageButtons.OK, MessageBoxIcon.Error)
    End If

    usersDatasSet.Dispose()
    Connection.Close()

    Return LoggedIn
End Function

现在,一种更好、更安全的方法将具有以下要素:

  1. 密码经过哈希处理(使用盐)并存储在您的数据库中。1a。您必须对他们输入的用户的纯文本密码进行哈希处理(使用正确的盐),并将其与存储在用户名表中的哈希值进行比较,以便他们成功登录。
  2. 限制尝试次数 - 如果超过尝试次数(例如 3 次),则帐户被锁定。这可以防止暴力攻击。
  3. 对表使用参数化查询来防止 SQL 注入攻击。我意识到这很可能是一个 WinForms 应用程序(基于对 MessageBox 的调用),但参数化查询是一个很好的编码实践。
于 2013-04-23T05:14:58.637 回答