Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中使用sql语句更改Oracle数据库的用户密码#_C#_Oracle - Fatal编程技术网

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

C# 在C中使用sql语句更改Oracle数据库的用户密码#,c#,oracle,C#,Oracle,我正在处理一项要求,即必须从应用程序中更改当前用户的oracle连接密码 我发现我可以使用以下语句使用SQL实现此任务: ALTER USER *username* IDENTIFIED BY *password* 但是,由于用户名和密码不是作为带引号的字符串发送到数据库的,所以我不能使用bind参数。(这个答案也是如此) 当我连接字符串并通过Entity Framework DbContext实例将其作为常规sql查询发送时,我有一个有效的解决方案,如下所示: using (var cont

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

我发现我可以使用以下语句使用SQL实现此任务:

ALTER USER *username* IDENTIFIED BY *password*
但是,由于用户名和密码不是作为带引号的字符串发送到数据库的,所以我不能使用bind参数。(这个答案也是如此)

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

using (var context = _dbContextFactory.CreateContext())
{
    await context.Database.ExecuteSqlCommandAsync(
      $"ALTER USER {username} IDENTIFIED BY \"{newPassword}\"");
}
这种方法的缺点是,通过在字符串中包含密码,我有SQL注入漏洞,用户不能在密码中使用一些保留字符,例如:;及"

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

有没有办法使用安全的方法从C#更改Oracle数据库中当前用户的密码?我也愿意使用其他方法,如不同的方法或在数据库中创建存储过程,只要它可以在C#客户端应用程序中实现


我们使用的是Oracle版本12+,因此我不能将值标识的
语法用于
用户名
,我们必须提供Oracle标识符(以防保留原始查询),该标识符是

  • 长度最多为30个字符
  • 必须以字母开头
  • 可以包括$(美元符号)、40;下划线)和#(散列符号)
我们可以通过正则表达式验证提供的值:

对于
密码
我们可以

  • 所有报价加倍:
    my“password
    ->
    my”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("\"", "\"\"")}\"");
}

这似乎在我的本地Oracle测试数据库(来自ODP.net驱动程序)上起作用。重要的一点似乎是开始/结束;(没有它就不行)


您将如何在SQLDeveloper中指定这些特殊字符?Oracle密码中可以使用哪些特殊字符?如果我没记错的话,密码要求非常严格,您不能使用
完全可以。验证用户输入可能足以阻止SQL注入。您可以尝试在服务器上的存储过程中使用
executeimmediate
?然后可以绑定到procparameters@ThomasN我们已经尝试过创建这样的进程,但是我们无法让它工作嘿,我试过了,看起来你甚至不需要服务器端进程。您可以声明开始/结束;直接由你指挥。我已经添加了一个答案,虽然它在ODP.net中。。。不知道这是否会帮助你,而不是一个自制的正则表达式,你也可以使用
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("\"", "\"\"")}\"");
}
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();
}