【问题标题】:Windows Forms Authentication for WinForms ApplicationWinForms 应用程序的 Windows 窗体身份验证
【发布时间】:2013-04-09 19:07:02
【问题描述】:

我正在我的 Visual Studio 2012 上使用 C# 和 .NET Framework 4.5 创建一个 Windows 窗体应用程序。

我现在想创建一个登录表单,用户可以在其中输入一些用户名和密码(之前在数据库中创建),然后应用程序验证并登录用户。如果可能的话,使用“角色控制”。

我尝试在 Google 上搜索,但我没有找到与 Windows 窗体相关的内容,只是在 ASP.NET 上。

.NET Framework 是否有任何好的(和官方的)解决方案来解决 WinForms 中的身份验证问题?

【问题讨论】:

    标签: c# winforms authentication .net-4.5 roles


    【解决方案1】:

    没有。 Membership 系统是 Asp.net 的一部分,虽然您可以在 winforms 应用程序中使用它,但它不是很干净。

    如果您已经在数据库中拥有用户名和密码,那么您最好的选择是直接实施身份验证系统,除非您担心人们对代码进行逆向工程...先进的东西,使其免受逆向工程的影响。

    编辑:

    Microsoft 确实有 Windows Identity Foundation,但它确实是一个比您可能想要的更复杂的系统。

    【讨论】:

    • 我明白了。我创建了用户数据库。如果用户存在且密码正确,我将创建这些数据的验证并显示仪表板表单。你怎么看?谢谢你的回复,顺便说一句。对不起我怪异的英语。 :)
    【解决方案2】:

    我通常会创建一个类似这样的新表单。

    public partial class LoginForm : Form
    {
        public bool letsGO = false;
    
        public LoginForm()
        {
            InitializeComponent();
            textUser.CharacterCasing = CharacterCasing.Upper;
        }
    
        public string UserName
        {
            get
            {
                return textUser.Text;
            }
        }
    
        private static DataTable LookupUser(string Username)
        {
            const string connStr = "Server=(local);" +
                                "Database=LabelPrinter;" +
                                "trusted_connection= true;" +
                                "integrated security= true;" +
                                "Connect Timeout=1000;";
    
            //"Data Source=apex2006sql;Initial Catalog=Leather;Integrated Security=True;";
    
            const string query = "Select password From dbo.UserTable (NOLOCK) Where UserName = @UserName";
            DataTable result = new DataTable();
            using (SqlConnection conn = new SqlConnection(connStr))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand(query, conn))
                {
                    cmd.Parameters.Add("@UserName", SqlDbType.VarChar).Value = Username;
                    using (SqlDataReader dr = cmd.ExecuteReader())
                    {
                        result.Load(dr);
                    }
                }
            }
            return result;
        }
    
        private void HoldButton()
        {
            if (string.IsNullOrEmpty(textUser.Text))
            {
                //Focus box before showing a message
                textUser.Focus();
                MessageBox.Show("Enter your username", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                //Focus again afterwards, sometimes people double click message boxes and select another control accidentally
                textUser.Focus();
                textPass.Clear();
                return;
            }
            else if (string.IsNullOrEmpty(textPass.Text))
            {
                textPass.Focus();
                MessageBox.Show("Enter your password", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                textPass.Focus();
                return;
    
            }
            //OK they enter a user and pass, lets see if they can authenticate
            using (DataTable dt = LookupUser(textUser.Text))
            {
                if (dt.Rows.Count == 0)
                {
                    textUser.Focus();
                    MessageBox.Show("Invalid username.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    textUser.Focus();
                    textUser.Clear();
                    textPass.Clear();
                    return;
                }
                else
                {
                    string dbPassword = Convert.ToString(dt.Rows[0]["Password"]);
                    string appPassword = Convert.ToString(textPass.Text); //we store the password as encrypted in the DB
    
                    Console.WriteLine(string.Compare(dbPassword, appPassword));
    
                    if (string.Compare(dbPassword, appPassword) == 0)
                    {
                        DialogResult = DialogResult.OK;
                        this.Close();
                    }
                    else
                    {
                        //You may want to use the same error message so they can't tell which field they got wrong
                        textPass.Focus();
                        MessageBox.Show("Invalid Password", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        textPass.Focus();
                        textPass.Clear();
                        return;
                    }
                }
            }
        }
    
        private void textPass_KeyDown_1(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                HoldButton();
            }
        }
    
        private void buttonLogin_Click(object sender, EventArgs e)
        {
            HoldButton();
        }
    
        private void textPass_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                HoldButton();
            }
        }
    }
    

    然后在您的主窗体中执行以下操作:

    public Form1(string userName)
    {
        //this is incase a user has a particular setting in your form
        //so pass name into contructer
    }
    

    最后:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
    
            LoginForm fLogin = new LoginForm();
    
            if (fLogin.ShowDialog() == DialogResult.OK)
            {
                Application.Run(new Form1(fLogin.UserName));
    
            }
            else
            {
                Application.Exit();
            }
    
            //Application.Run(new Form1());
        }
    

    希望这可以让您大致了解该怎么做,尽管我确信他们的做法会更好,但请注意这并不是真正安全的前端。

    希望这会有所帮助:

    编辑:哦,在我忘记之前不要使用

    Select password From dbo.UserTable (NOLOCK) Where UserName = @UserName 
    

    我只是把它扔到一个存储过程中。但无论如何,这不是最好的身份验证方式,但它至少是一个可行的解决方案,我希望你能继续前进

    【讨论】:

      猜你喜欢
      • 2013-02-19
      • 2021-01-10
      • 1970-01-01
      • 2012-11-01
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多