在VB.net中尝试登录失败后系统锁定

时间:2013-03-26 01:40:51

标签: vb.net security ms-access login block

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

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 个答案:

答案 0 :(得分: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之后移动到con.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 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 namespace哈希。

答案 1 :(得分:0)

我不完全确定我理解这个问题。但是这部分让我听起来像是在尝试在程序中失败三次失败三次后,计算机的整个桌面锁定

  

我尝试做的是当用户未能登录系统3次时,系统将显示另一个表示系统已锁定的表单,用户需要输入系统密码才能尝试再次登录

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

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

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

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

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

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 keyword声明变量,如下所示:

Static ErrorCount As Integer = 0

测试这些东西并弄清楚错误的一个很好的方法是在btnLogin_Check方法中设置一个断点,并确切地看到变量的值!如果你这样做,你会注意到每次执行经过第一行后ErrorCount被设置为0。这将是您对问题所在的直接线索。然后你只需要弄清楚如何使价值坚持下去。现在你知道你使用Static关键字(或者移动范围,比如使它成为Form类的成员,以便它与该类的对象一样长)。

答案 2 :(得分:-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

最好的问候

答案 3 :(得分:-1)

Imports System.Data.OleDb

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

结束班