我正在处理一个要求,我必须从我的应用程序更改当前用户的 oracle 连接密码。
我发现我可以使用以下语句使用 SQL 来完成此任务:
ALTER USER *username* IDENTIFIED BY *password*
但是因为用户名和密码没有作为带引号的字符串发送到数据库,所以我不能使用绑定(bind)参数。 (这也是此答案的 stated)
当我连接一个字符串并将其作为常规 sql 查询发送到我的 Entity Framework DbContext 实例时,我有一个可行的解决方案,如下所示:
using (var context = _dbContextFactory.CreateContext())
{
await context.Database.ExecuteSqlCommandAsync(
$"ALTER USER {username} IDENTIFIED BY \"{newPassword}\"");
}
这种方法的缺点是,通过在字符串中连接密码,我有 SQL 注入(inject)漏洞,并且用户不能在他们的密码中使用一些保留字符,例如;和“
我不关心用户名参数,因为这是在后端代码中管理的,但是密码直接来自用户输入。
有什么方法可以使用安全的方法从 C# 更改 Oracle 数据库中的当前用户密码?我也愿意接受其他方法,例如不同的方法或在数据库中创建存储过程,只要它可以在 C# 客户端应用程序中实现即可。
我们使用的是 Oracle 版本 12+,所以我不能使用 IDENTIFIED BY VALUES ''
语法
最佳答案
对于 username
,我们必须提供 Oracle 标识符(以防我们保留原始查询)
- 最多 30 个字符
- 必须以字母开头
- 可以包含 $(美元符号)、_(下划线)和 #(井号)
我们可以通过正则表达式验证提供的值:
if (!Regex.IsMatch(username, @"^[A-Za-z][A-Za-z0-9_#\$]{0,29}$")) {
// username is invalid
}
对于密码
我们可以
- 双引号:
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("\"", "\"\"")}\"");
}
关于c# - 在 C# 中使用 sql 语句更改 Oracle 数据库的用户密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54128017/