如何实现密码更改功能与Oracle和.NET客户端? [英] How to implement a password change functionality with Oracle and a .Net client?

查看:181
本文介绍了如何实现密码更改功能与Oracle和.NET客户端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是用Oracle用户的.NET应用程序验证用户名和密码。现在,我正在更改密码功能。该数据库有一个自定义密码验证,因此,如果您尝试更改用户密码,你提供的密码无效,Oracle返回多个错误。

I'm using Oracle users to authenticate username and password for a .Net application. Right now I'm working on the password change function. The database has a custom password validation, so if you try to change a users password and you provide an invalid password, Oracle returns multiple errors.

第一个错误是总是ORA-28003:口令验证指定的密码失败,然后将其上升有一个错误的每个验证失败。这是正确显示当我尝试从蟾蜍客户端更改用户的密码。

The first error is always "ORA-28003: password verification for the specified password failed", and then it rises one error for each failed validation. This is shown correctly when I try to change a user's password from the Toad client.

然而,当我做到这一点从我的应用程序,也就是提高了OracleException只返回第一个错误,因此我不能向用户展示什么是关于新的密码,他提供的,这对于要求无效应用。所以,我应该怎样的形式给出这个?

However, when I do this from my application, the OracleException that is raised only returns the first error, and therefore I'm not able to show the user what's invalid about the new password he provided, which is a requirement for the application. So how should I aproach this?

推荐答案

首先,不使用OpenWithNewPassword方法。它不仅具有已知问题与各种版本ODP.net和DB的,但它迫使你有code两个不同的分支时,你只需要一个 - IIRC它不工作,如果用户的密码已已经过期。

For starters, don't use the OpenWithNewPassword method. Not only does it have known issues with with various versions of ODP.net and the DB, but it forces you to have two different branches of code when you only need one - IIRC it doesn't work if the user's password has already expired.

相反,基本的逻辑是这样的:

Instead the basic logic works like this:

  • 请确保您可以与用户的旧帐户和密码

  • Make sure you can authenticate with the user's old account and password

如果你成功了,关闭了连接,并打开没有访问不是在的ChangePassword存储过程。

If you're successful, close that connection and open a separate account that has no access other than exec privs on a ChangePassword stored procedure.

这里的code:

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


      }
    }
  }

在它最简单的形式中,proc执行更改用户标识和将是一个类似于记录在这里:的 http://www.adp-gmbh.ch/ora/plsql/change_password.html 。然而,DBMS_OUTPUT行不会做你多好,所以你可以抛出定制的异常,而不是:

In it's simplest form, the proc executes 'alter user identified by and would be similar to the one documented here: http://www.adp-gmbh.ch/ora/plsql/change_password.html. However the dbms_output lines don't do you much good so you could throw custom exceptions instead:

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

拥有此过程的架构需要修改任何用户privleges。为安全起见,您的应用程序要连接为一个单独的用户,只有对这个进程内执行PRIVS。而

The schema that owns this procedure needs 'alter any user' privleges. For safety's sake, your app should connect as a separate user that only has execute privs on this proc. Rather

这篇关于如何实现密码更改功能与Oracle和.NET客户端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆