如何用Oracle和.net客户端实现密码修改功能
本文关键字:实现 密码 修改 功能 客户端 net 何用 Oracle | 更新日期: 2023-09-27 18:08:24
我使用Oracle用户来验证。net应用程序的用户名和密码。现在我正在研究密码修改功能。数据库有一个自定义的密码验证,所以如果你试图修改一个用户的密码,你提供了一个无效的密码,Oracle将返回多个错误。
第一个错误始终是"ORA-28003: password verification for The specified password failed",然后每验证失败一次就上升一个错误。当我尝试从Toad客户端更改用户的密码时,会正确地显示这一点。
然而,当我从我的应用程序中执行此操作时,引发的OracleException只返回第一个错误,因此我无法向用户显示他提供的新密码无效的地方,这是应用程序的要求。那么我应该怎么做呢?
对于初学者,不要使用OpenWithNewPassword方法。它不仅与各种版本的ODP.net和DB有已知的问题,而且当你只需要一个代码分支时,它迫使你有两个不同的代码分支- IIRC如果用户的密码已经过期,它就不起作用。
相反,基本逻辑是这样工作的:
-
确保您可以使用用户的旧帐户和密码进行身份验证
-
如果成功,关闭该连接并打开一个单独的帐户,该帐户除了对ChangePassword存储过程的exec权限外没有其他访问权限。
代码如下:
protected void BtnChangePassword_Click(object sender, EventArgs e)
{
String connectionStringFormat = "Data Source={0};User Id={1};Password={2};pooling=false;";
if (Page.IsValid)
{
Boolean hasHasError = false;
String connectionString = String.Format(
connectionStringFormat,
IptDatabase.Text,
IptUserName.Text,
IptOldPassword.Text);
OracleCommand cmd = new OracleCommand();
using (cmd.Connection = new OracleConnection(connectionString))
{
try
{
cmd.Connection.Open();
}
catch (OracleException ex)
{
//allow to continue if the password is simply expired, otherwise just show the message
if (ex.Number != 28001)
{
ShowErrorMessage(ex.Message);
hasHasError = true;
}
}
if (!hasHasError)
{
//successful authentication, open as password change account
cmd.Connection.Close();
cmd.Connection.ConnectionString = ConfigurationManager.ConnectionStrings[IptDatabase.Text].ConnectionString;
cmd.Connection.Open();
cmd.CommandText = "SysChangePassword";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("username", IptUserName.Text);
cmd.Parameters.Add("newpassword", IptPassword.Text);
try
{
cmd.ExecuteNonQuery();
ShowInfoMessage("Password Changed");
}
catch (OracleException ex)
{
ShowErrorMessage(ex.Message);
}
}
}
}
在最简单的形式中,该过程执行'alter user ',由和标识,类似于这里记录的:http://www.adp-gmbh.ch/ora/plsql/change_password.html。然而,dbms_output行并没有给您带来太多好处,因此您可以抛出自定义异常:
create or replace procedure SysChangePassword(
pUserName in varchar2,
pPassWord in Varchar2) as
begin
-- Check for system users here and reject
if upper(pUserName) in ('SYS','SYSTEM') then
raise_application_error(-20012, 'not allowed');
else
execute immediate 'alter user '||pUserName||' identified by ' ||
pPassWord;
end if;
exception --this isn't necessary if you'd rather examine and handle the specific exceptions on the .net side
when others then
raise_application_error(-20012, sqlerrm);
end;
/
拥有这个过程的模式需要'alter any user'权限。为了安全起见,你的应用程序应该作为一个单独的用户来连接,这个用户在这个进程上只有执行权限。
为什么不在存储过程中封装逻辑呢?它将调用Oracle密码验证函数,然后根据需要解析结果,并将您想要的任何消息返回给。net客户端。
如果为ASP编写程序,为什么不使用正则表达式验证器控件呢?. NET,或Regex.IsMatch(…)编写桌面应用程序的功能?为什么必须先到服务器获取生成的错误。您有强大的密码策略,您可以在客户端限制用户