【问题标题】:Connection problem when changing password更改密码时出现连接问题
【发布时间】:2019-06-24 08:17:29
【问题描述】:

我有一个软件可以显示我们 SQL 数据库中的一些表。现在我想添加一个工具,我可以在其中更改“testdummy”用户的密码。

我尝试再次打开连接,但没有帮助。如果您需要一些额外的代码或信息,只需写评论即可。

请注意,我是编程新手。我是一名学徒,目前正在学习编程和管理数据库。我知道这不是最安全的解决方案,但这只是我的导师的一项小任务。此软件不会面向客户发布。

就像我之前提到的,在我想更改密码之前,我尝试再次打开连接。

 public void Change()
        {
            SqlConnection con = new SqlConnection();
            string connectionString = GetConnectionString();


            if (NewPassword.Password == NewPasswordAgain.Password && OldPassword.Password == GlobalData.Password)
            {
                try
                {
                    //dbMan.TryConnect(connectionString);
                    //con.Open();
                    SqlConnection.ChangePassword($"Data Source={GlobalData.ServerName};Initial Catalog={GlobalData.DBName};UID={GlobalData.Username};PWD={OldPassword}", $"{NewPassword}");
                }
                catch (SqlException ex)
                {
                    MessageBox.Show("Unable to change password. Try again!" + ex);
                }
            }
            else
            {
                // If new Password doesn't match.
                MessageBox.Show("Passwords doesn't match!");
            }
        }

我在尝试更改密码时遇到 SQL 异常。

(System.Data.SqlClient.SqlException (0x80131904): Login failed for user 'csharptest'.

我在:

SqlConnection.ChangePassword($"Data Source={GlobalData.ServerName};Initial Catalog={GlobalData.DBName};UID={GlobalData.Username};PWD={OldPassword}", $"{NewPassword}");

此时程序应该有一个到数据库的连接,因为我可以处理一些表和操作数据集。

但是当我取消注释时:

//dbMan.TryConnect(connectionString);
//con.Open();

它进入了那里的捕获括号:

public bool TryConnect(string connectionString)
        {
            conn = new SqlConnection();
            conn.ConnectionString = connectionString;

            try
            {
                conn.Open();
                return true;
            }
            catch (Exception)
            {
                MessageBox.Show("Couldn't connect");
                return false;
            }
        }

并返回以下异常:

System.InvalidOperationException: 'Die ConnectionString-Eigenschaft wurde nicht initialisiert.'

英文应该是这样的:“连接字符串属性尚未初始化”

编辑: 在日志中我得到了这个:

Login failed for user 'csharptest'. Reason: Password did not match that for the login provided.

编辑: 而不是:

SqlConnection.ChangePassword($"Data Source={GlobalData.ServerName};Initial Catalog={GlobalData.DBName};UID={GlobalData.Username};PWD={OldPassword}", $"{NewPassword}");

我这样做了:

string updatePassword = "USE CSHARPTEST ALTER LOGIN [" + GlobalData.Username + "] WITH PASSWORD =  '" + NewPassword + "'";
con.Open();
cmd.ExecuteNonQuery();

现在我认为唯一的问题是服务器上的权限。

【问题讨论】:

  • 您使用的是 Windows 凭据还是 SQL 数据库凭据?您不能更改 Windows 凭据。
  • 我正在使用 SQL 数据库凭据。
  • 尝试关闭 c# 应用程序并重新打开。我经常发现对数据库结构的更改需要在更改生效之前关闭 c#。当我在 c# 中将数据库附加到服务器时,经常会发现这种情况。
  • 我是否正确理解此应用程序正在更改其自己的密码?哎呀,这是一个高级问题,如果您希望它具有容错性,并且更改密码可能会出现很多问题(复杂性规则等)并且如果您对此草率,则可以触发锁定.你试过关注Microsoft's example吗?看起来相当投入。 for (int i = 0; i <= 1; i++)ZOMG

标签: c#


【解决方案1】:

您需要在 DbContext 级别使用参数。有关更多详细信息,请参阅此答案,但是,这是一个代码示例(改编自同一页面):

string sql = "ALTER LOGIN @loginName WITH PASSWORD = @password";
ctx.Database.ExecuteSqlCommand(
    sql,
    new SqlParameter("loginName", loginName),
    new SqlParameter("password", password));

在此处(以及在任何地方)使用参数的目的是防止 SQL 注入攻击。鉴于您正在编写更改密码的代码,这一点尤其重要。

更新

ALTER LOGIN 语句不适用于变量;它必须通过动态 SQL 来完成。以下是更新代码的示例:

string sql = @"DECLARE @sql NVARCHAR(500)
               SET @sql = 'ALTER LOGIN ' + QuoteName(@loginName) + 
                    ' WITH PASSWORD= ' + QuoteName(@password, '''') 
               EXEC @sql ";
ctx.Database.ExecuteSqlCommand(
    sql,
    new SqlParameter("loginName", loginName),
    new SqlParameter("password", password));

请注意,我们仍在使用 SqlParameters 来防止 SQL 注入攻击。我们还使用 T-SQL 方法 QuoteName 在我们生成的 SQL 中进行适当的引用;但是此方法只是将任何 [ 字符(在第一次调用中)或 ' 字符(在第二次调用中)加倍。 SQL 注入攻击还有很多其他的载体,所以仅仅依靠 QuoteName 是不够的。

【讨论】:

猜你喜欢
  • 2021-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 2020-08-22
  • 1970-01-01
相关资源
最近更新 更多