当密码包含问号字符时,我在更改用户密码时遇到问题。到目前为止,我没有遇到任何其他char的这个问题,它似乎特定于问号char。
如果我使用以下sql更改sqlplus中的用户密码:
Alter user Stephen identifed by "NewPassword?" REPLACE "OldPassword";
然后它成功更改了传递,我可以使用新传递'NewPassword?'登录。
但是如果我通过jdbc执行相同的SQL:
final String query = "ALTER user Stephen identified by \"NewPassword?\" REPLACE \"OldPassword\"";
stmt.executeUpdate(query);
然后我无法使用传递'NewPassword?'登录。
通过sqlplus和jdbc输入时检查密码的哈希码表明它们不同。 不知怎的,当我在jdbc中运行语句时,它正在输入“NewPassword?”之外的其他内容。
以下密码似乎没有任何问题: NewPassword,NewPassword \,NewPassword'。它似乎只是引起问题的问号 调试显示问号的代码点(dec)为63,因此它看起来不像是在中途改变。
有谁知道可能导致此行为的原因是什么? 我现在不知所措,我正在考虑阻止带问号的通行证现在绕过这个问题。
答案 0 :(得分:5)
要使用JDBC更改Oracle用户的密码,您需要做两件事:
您不能使用绑定变量,因为用户名和密码不会作为单引号字符串发送到数据库。
SQL字符串中的?
被视为绑定变量占位符,因此,Oracle JDBC在某些时候会破坏SQL字符串。禁用语句上的转义处理可以防止这种情况发生。尝试:
Statement s = conn.createStatement();
s.setEscapeProcessing(false);
s.executeUpdate("ALTER user Stephen identified by \"newPassword?\" replace \"oldPassword\"");
如果以编程方式设置密码,则代码还应确保新密码和旧密码不包含任何"
个字符,以避免SQL注入。
答案 1 :(得分:2)
尝试使用PreparedStatement
实现它,看看是否遇到同样的问题。问号在PreparedStatements
中用作占位符,因此JDBC驱动程序可能会变得混乱。它不应该,但可能值得检查。
PreparedStatement p = conn.prepareStatement("ALTER user Stephen identified by ? replace ?");
p.setString(1, "NewPassword?");
p.setString(2, "OldPassword");
p.execute();
如果这样可行,则可能是驱动程序中的错误。