在C#中使用sql语句更改Oracle数据库的用户密码

时间:2019-01-10 11:46:55

标签: c# oracle

我正在处理一项要求,必须从应用程序中更改当前用户的oracle连接密码。

我发现我可以使用以下语句通过SQL完成此任务:

ALTER USER *username* IDENTIFIED BY *password*

但是,因为用户名和密码未作为带引号的字符串发送到数据库,所以不能使用绑定参数。 (此答案也是stated的人)

当我连接一个字符串并将其作为常规sql查询通过我的Entity Framework DbContext实例发送时,我有一个可行的解决方案,如下所示:

using (var context = _dbContextFactory.CreateContext())
{
    await context.Database.ExecuteSqlCommandAsync(
      $"ALTER USER {username} IDENTIFIED BY \"{newPassword}\"");
}

这种方法的缺点是,通过在字符串中隐藏密码,我具有SQL注入漏洞,并且用户无法在密码中使用某些保留字符,例如;和“

我不关心username参数,因为它是在后端代码中管理的,但是密码直接来自用户输入。

是否可以使用安全方法从C#更改Oracle数据库中的当前用户密码?我也愿意接受其他方法,例如差异方法或在数据库中创建存储过程,只要它可以在C#客户端应用程序中实现即可。

我们正在使用Oracle 12+版本,因此我无法使用IDENTIFIED BY VALUES ''语法

2 个答案:

答案 0 :(得分:2)

对于username,我们必须提供 Oracle标识符(如果我们保留原始查询)

  • 最多30个字符
  • 必须以字母开头
  • 可以包含$(美元符号),_(下划线)和#(哈希符号)

我们可以通过正则表达式来验证提供的值:

if (!Regex.IsMatch(username, @"^[A-Za-z][A-Za-z0-9_#\$]{0,29}$")) {
  // username is invalid
}

对于password,我们可以

  • 双引号:my"password-> my""password
  • 确保password仅包含有效字符(例如,让我们排除Unicode 控制字符,例如退格键和其他字符)

所以代码将是这样的

if (!Regex.IsMatch(username, @"^[A-Za-z][A-Za-z0-9_#\$]$")) {
  // username is invalid
}

if (string.IsNullOrEmpty(newPassword) || newPassword.Any(c => char.IsControl(c))) {
  // password is invalid
}

using (var context = _dbContextFactory.CreateContext()) {
  await context.Database.ExecuteSqlCommandAsync(
    $"ALTER USER {username} IDENTIFIED BY \"{newPassword.Replace("\"", "\"\"")}\"");
}

答案 1 :(得分:0)

这似乎在我的本地Oracle测试数据库上起作用(来自ODP.net驱动程序)。重要的一点似乎是BEGIN / END; (没有它就无法工作)。

using (var con = (OracleConnection)db.Server.GetConnection())
{
    con.Open();

    //string pw = "'''';++";
    string pw = "newpass";

    var cmd = new OracleCommand(@"
BEGIN
EXECUTE IMMEDIATE CONCAT('ALTER USER B identified by ',:pw);
END;", con);
    cmd.CommandType = CommandType.Text;

    var p2 = cmd.CreateParameter();
    p2.ParameterName = "pw";
    p2.Value = pw;
    p2.DbType = DbType.String;
    cmd.Parameters.Add(p2);

    cmd.ExecuteNonQuery();
}