1

我将此代码用于我的登录表单:

Private Sub btnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLogin.Click
    Dim ErrorCount As Integer = 0

    If (ErrorCount = 3) Then
        MessageBox.Show(" The System has been Lock ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Form3.Show()
    Else

        Dim con As OleDbConnection = New OleDbConnection( _
                   "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= UserPass.mdb;")
        con.Open()
        Dim str As String
        str = "SELECT * FROM UserPass WHERE Username='" & txtUsername.Text & "' AND Password='" & txtPassword.Text & "'"
        Dim cmd As OleDbCommand = New OleDbCommand(str, con)
        cmd.Parameters.AddWithValue("user", txtUsername.Text)
        cmd.Parameters.AddWithValue("pass", txtPassword.Text)
        Dim sdr As OleDbDataReader = cmd.ExecuteReader()
        ' It will be case sensitive if you compare usernames here.   
        If sdr.HasRows Then
            If sdr.Read Then
                If txtPassword.Text <> sdr("Password").ToString Or txtUsername.Text <> sdr("Username").ToString Then
                    MessageBox.Show(" Incorrect Username/Password. Login Denied ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    ErrorCount = ErrorCount + 1
                Else
                    MessageBox.Show(" You are now Logged In! ", " Welcome! ", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
                    frmOne.Show()
                    Me.Hide()
                End If
            End If
        Else
            MessageBox.Show(" Incorrect Username/Password. Login Denied ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If


        sdr.Close()
        con.Close()
    End If

我试图做的是当用户登录系统 3 次失败时,系统将显示另一种形式,说明系统已锁定,用户需要输入系统密码才能尝试登录-再次进入。请帮忙。

我使用 ms 访问作为用户名和密码的数据库

4

4 回答 4

2

结合其他两个答案。您需要将声明更改为静态,以便它保持状态。Dim ErrorCount As Integer = 0Static ErrorCount As Integer

您还需要在用户输入无效用户名的代码路径中添加减量。

MessageBox.Show(" Incorrect Username/Password. Login Denied ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)
ErrorCount = ErrorCount + 1 'add this here

然后移动 if 使其位于 SQL 之后,因此将其移至 aftercon.close()

If (ErrorCount = 3) Then
    MessageBox.Show(" The System has been Lock ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)
    Form3.Show()
Else

此外,您似乎对参数化查询有些困惑。如果您使用参数化查询,那么您不需要连接您的 SQL,这应该是

    str = "SELECT * FROM UserPass WHERE Username=@user AND Password=@pass"

在正常情况下,内部 if 也不应该为真

If txtPassword.Text <> sdr("Password").ToString Or txtUsername.Text <> sdr("Username").ToString Then 
     ' this code path is only evaluated if the database ignores the where clause or 
     ' the user changes the username or password textboxs whilst the database connection is proccessing and is therfore unnessacary 
     MessageBox.Show(" Incorrect Username/Password. Login Denied ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)
     ErrorCount = ErrorCount + 1
Else
     MessageBox.Show(" You are now Logged In! ", " Welcome! ", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
     frmOne.Show()
     Me.Hide()
End If

最后不要将密码存储为明文。使用带有盐的System.Security.Cryptography命名空间中的哈希。

于 2013-03-27T10:55:01.857 回答
0

我不完全确定我理解这个问题。但是这部分让我觉得你在程序中的登录尝试失败了 3 次后试图锁定计算机的整个桌面:

我试图做的是当用户登录系统 3 次失败时,系统将显示另一种形式,说明系统已锁定,用户需要输入系统密码才能尝试登录-再次进入。

我不确定这是个好主意。仅仅将用户锁定在您的程序之外而不是锁定整个计算机还不够吗?可以这样想:没有理由对本地违规行为施加全球惩罚。

但是,不管我是否认为这是一个好主意,VB.NET 完全可以做到这一点。您需要做的就是LockWorkStation在您的计数器指示发生了 3 次失败的登录尝试后调用该函数。此函数作为 Win32 API 的一部分提供,因此要直接从 .NET 应用程序调用它,您需要使用 P/Invoke。这个函数有一个相对简单的签名,所以它的定义也不应该太难理解:

<DllImport("user32.dll", SetLastError=True)> _
Public Shared Function LockWorkStation() As Boolean
End Function

这个函数的使用有一些重要的限制,即它只能被交互式桌面上运行的进程调用。不过,这对您来说不是问题,因为您正在构建一个只能在交互式桌面上运行的 GUI 应用程序,并且您知道如果有人输入了 3 次无效密码,那么他们肯定已经登录并坐在离键盘几英尺。

从代码中调用魔法相对简单,尽管函数可能会失败并且您应该处理这些错误情况(以免有人在您的应用程序中找到安全后门):

If (FailedLogonAttempts < 3) Then
    ' Do whatever...
Else
    ' Lock 'em out!
    Dim success As Boolean = LockWorkstation()
    If Not success Then
        ' Uh-oh! An error occurred! You need to handle this, otherwise someone
        ' might be able to gain unauthorized access to the system.
        '
        ' For demonstration and debugging purposes, we'll throw an exception,
        ' but that's obviously not a secure long-term solution.
        Throw New Win32Exception(Marshal.GetLastWin32Error())
    End If
End If

如果您只是询问如何修复现有代码,问题是您的ErrorCode变量永远不会超过 0。您已在btnLogin_Click方法顶部声明它,如下所示:

Dim ErrorCount As Integer = 0

这是具有方法级范围的常规变量。这意味着每次方法运行并且不保留其值时,它都会重新初始化(就像您要求的那样为 0)。

如果要声明具有保留其值的方法级范围的变量,需要使用Static关键字声明变量,如下所示:

Static ErrorCount As Integer = 0

测试这些东西并找出问题所在的一个好方法是在btnLogin_Check方法内部设置一个断点并准确查看变量的值!ErrorCount如果你这样做了,你会注意到,在执行通过第一行之后,每次都设置为 0。这将是您对问题所在的直接线索。然后你只需要弄清楚如何让价值坚持下去。现在您知道您使用Static关键字(或向上移动范围,例如使其成为 Form 类的成员,以便它与该类的对象一样长)来执行此操作。

于 2013-03-26T02:51:56.667 回答
-1
Imports System.Data.OleDb

公共类 Form1 私人尝试 As Integer = 3

Private Sub cmdLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLogin.Click
    Dim cn As New OleDbConnection("Provider=Microsoft.Ace.Oledb.12.0; Data Source=" & My.Application.Info.DirectoryPath.ToString() & "\BackUp\testing.Accdb;")
    cn.Open()
    If txtpassword.Text = "" Then
        MsgBox("Please Enter Your Password !!!", MsgBoxStyle.Critical, "Attention...")
        Exit Sub
    End If

    Dim dr1 As OleDbDataReader
    Dim com1 As New OleDbCommand

    com1.CommandText = "select [UserID],[Pass] from userinfo where userid = '" & txtUserID.Text & "'"
    com1.Connection = cn
    If cn.State = ConnectionState.Closed Then cn.Open()
    dr1 = com1.ExecuteReader
    If dr1.Read Then
        If UCase(dr1("Pass")) = UCase(txtpassword.Text) Then
            MessageBox.Show("Welecome")
            Me.Close()
        Else
            MessageBox.Show("Wrong Password  [" & attempt - 1 & "]  Attempt(s) Remaing")
            attempt -= 1
            txtpassword.Focus()
            If attempt = 0 Then
                End
            End If
        End If
        Exit Sub

    Else
        MessageBox.Show("Wrong UserID  [" & attempt - 1 & "]  Attempt(s) Remaing")
        attempt -= 1
        txtpassword.Focus()
        If attempt = 0 Then
            End
        End If
    End If
    cn.Close()
End Sub

Private Sub cmdCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCancel.Click
    End
End Sub

Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    Me.Dispose()
End Sub

结束类

于 2013-03-27T10:18:03.130 回答
-1

你可以尝试这样的事情:

Dim ErrorCount As Int = 0

If (ErrorCount =3) Then
     MessageBox.Show(" The System has been Lock ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)

'Do stuff 
'Add Your Code to show new Form something like
 Me.Hide()
 Form3.Show()


Else 

Dim con As OleDbConnection = New OleDbConnection( _
           "Provider=Microsoft.Jet.OLEDB.4.0;Data Source= UserPass.mdb;")


con.Open()
Dim str As String
str = "SELECT * FROM UserPass WHERE Username='" & txtUsername.Text & "' AND Password='" & txtPassword.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, con)
cmd.Parameters.AddWithValue("user", txtUsername.Text)
cmd.Parameters.AddWithValue("pass", txtPassword.Text)
Dim sdr As OleDbDataReader = cmd.ExecuteReader()
' It will be case sensitive if you compare usernames here.   
If sdr.HasRows Then
    If sdr.Read Then
        If txtPassword.Text <> sdr("Password").ToString Or txtUsername.Text <> sdr("Username").ToString Then
            MessageBox.Show(" Incorrect Username/Password. Login Denied ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)

             ErrorCount = ErrorCount + 1 

        Else
            MessageBox.Show(" You are now Logged In! ", " Welcome! ", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
            frmOne.Show()
            Me.Hide()
        End If
    End If
Else
    MessageBox.Show(" Incorrect Username/Password. Login Denied ", " Error! ", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If

    sdr.Close()
    con.Close()

End If

此致

于 2013-03-26T01:54:48.363 回答