如何使用Oracle和.Net客户端实现密码更改function?

我正在使用Oracle用户来validation.Net应用程序的用户名和密码。 现在我正在研究密码更改function。 数据库具有自定义密码validation,因此,如果您尝试更改用户密码并提供无效密码,Oracle将返回多个错误。

第一个错误始终是“ORA-28003:指定密码的密码validation失败”,然后每次失败validation都会出现一个错误。 当我尝试从Toad客户端更改用户密码时,会正确显示。

但是,当我从我的应用程序执行此操作时,引发的OracleException仅返回第一个错误,因此我无法向用户显示他提供的新密码无效,这是应用程序的要求。 那我该怎么办呢?

对于初学者,请不要使用OpenWithNewPassword方法。 它不仅与ODP.net和数据库的各种版本存在已知问题,而且当您只需要一个代码时,它会强制您拥有两个不同的代码分支 – 如果用户的密码已经过期,则它不起作用。

相反,基本逻辑的工作原理如下:

  • 确保您可以使用用户的旧帐户和密码进行身份validation

  • 如果您成功,请关闭该连接并在ChangePassword存储过程中打开一个除exec privs之外无法访问的单独帐户。

这是代码:

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); } } } } 

在它最简单的forms中,proc执行’alter user标识,并且类似于此处记录的用户: http : //www.adp-gmbh.ch/ora/plsql/change_password.html 。 但是dbms_output行对你没那么好,所以你可以抛出自定义exception:

 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; / 

拥有此过程的架构需要“更改任何用户”权限。 为安全起见,您的应用程序应作为一个单独的用户连接,该用户在此proc上只有执行权限。 宁

为什么不将逻辑包装在存储过程中? 它将调用Oracle密码validation函数,然后根据需要解析结果,并将您想要的任何消息返回给.net客户端?

如果为ASP.NET编写,或者为了编写桌面应用程序而使用Regex.IsMatch(…)函数,为什么不使用正则表达式validation器控件? 为什么必须先去服务器才能生成错误。 您有强密码策略,并且可以在客户端限制用户。