首页 文章

使用Java,Oracle JDBC进行Oracle密码到期和宽限期处理

提问于
浏览
1

我有一个Oracle 11g数据库,我编写了一个应用程序,它与许多其他能够创建用户的东西一起编写 . 我希望使用该帐户的最终用户在创建后更改密码,因此我在创建用户时设置了 pasword expire 子句 .

所以现在我的问题是如何处理java中的 ORA-28001: the password has expired 异常,因此用户可以根据需要更改密码 . grace period 设置为2天 .

这就是我得到的整个错误信息:

openCon():  URL = jdbc:oracle:thin:@//xxx.xxx.xxx.xxxx:xxxx/dbName username = asd password = mypasswordwhichisexpired
    java.sql.SQLException: ORA-28001: the password has expired

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:389)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:382)
at oracle.jdbc.driver.T4CTTIfun.processError(T4CTTIfun.java:600)
at oracle.jdbc.driver.T4CTTIoauthenticate.processError(T4CTTIoauthenticate.java:445)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:380)
at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:760)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at at.nje.DataBaseOp.ConnectOrcl.openCon(ConnectOrcl.java:73)
at at.nje.Kone.GUI.LoginFrame.login(LoginFrame.java:126)
at at.nje.Kone.GUI.LoginFrame$3.actionPerformed(LoginFrame.java:67)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

提前致谢

编辑:

这是我的openCon()方法的代码:

public final Connection openCon(){  
        Properties prop = new Properties();
        try{
            System.out.println("openCon():  URL = "+url+" username = "+user+" password = "+ pw);
            prop.setProperty("user", user);
            prop.setProperty("password", pw);
            con = (OracleConnection) DriverManager.getConnection(url,prop); 
            con.setAutoCommit(false);
            System.out.println("oracle con ok");            
            return con;
        }catch(SQLException e){
            e.printStackTrace();
            String errMessage = e.getMessage();
            System.out.println("oracle con not opened because: "+errMessage);
            JOptionPane.showMessageDialog (null, "Login Error", "You shall not pass", JOptionPane.INFORMATION_MESSAGE);         
        }
        return null;
}

编辑:好的,谢谢我试过这个但仍然得到ora 28001:

public final Connection openCon(){  
    Properties prop = new Properties();
        try{
            System.out.println("openCon():  URL = "+url+" username = "+user+" password = "+ pw);
            prop.setProperty("user", user);
            prop.setProperty("password", pw);
            con = (OracleConnection) DriverManager.getConnection(url,prop); 
            con.setAutoCommit(false);
            System.out.println("oracle con ok");            
            return con;
        }catch(SQLException e){
            e.printStackTrace();
            String errMessage = e.getMessage();
            System.out.println("oracle con not opened because: "+errMessage);
            EnterNewPwPanel panel = new EnterNewPwPanel();
            if (e.getErrorCode() == 28001) {                    
                int result = JOptionPane.showConfirmDialog(null, panel, 
                        "Please Enter X and Y Values", JOptionPane.OK_CANCEL_OPTION);
                if(result == JOptionPane.OK_OPTION){
                    String npw = panel.getNewPw();
                    System.out.println("npw: "+npw);

                    prop.setProperty("user", user); // username is correct
                    prop.setProperty("password", pw); // pw is expired but correct
                    prop.setProperty(OracleConnection.CONNECTION_PROPERTY_SET_NEW_PASSWORD, npw);
                        try {
                            con = (OracleConnection) DriverManager.getConnection (url,prop);
                        } catch (SQLException e1) {
                            e1.printStackTrace();
                            System.out.println("setting new pw didnt work after all");
                        }
                }else
                    System.out.println("your pw will expire in x days maddafakka");
            } else {
                JOptionPane.showMessageDialog (null, "Login Error", "You shall not pass", JOptionPane.INFORMATION_MESSAGE);   
                //throw(ex);        // for example, just let our caller handle it
            }

        }
        return null;
}

之后,我得到了与之前相同的错误输出

再次编辑:

好吧,我以为我有它但是没有,毕竟没有工作,nether字段新密码也没有字段值新pw使用这个网址: static String url = "jdbc:oracle:thin:@//192.168.97.10:1521/orcl" :不是这个

prop.setProperty("user", user);
                    prop.setProperty("password", pw);                       
                    prop.setProperty("OracleConnection.CONNECTION_PROPERTY_SET_NEW_PASSWORD", npw);

也不是这个

prop.setProperty("OciNewPassword", npw);

3 回答

  • 0

    //这是使用Oracle 12.2 jdbc瘦驱动程序更改过期密码的示例代码 - ojdbc8.jar

    DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
    
    
    java.util.Properties connInfo = new java.util.Properties();
    
    connInfo.put("user","myuser");
    
    connInfo.put("password","OldPassword");
    
    connInfo.put("database","myhost:1521:mysid");
    
    
    connInfo.setProperty(OracleConnection.CONNECTION_PROPERTY_NEW_PASSWORD,"NewPassword");
    
    
    Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@", connInfo);
    
    // password changed
    
    conn.close();
    
  • 2

    如果您发布了一些代码,它会有所帮助 . 堆栈提示有关一个swing应用程序,当你按下按钮时它会启动oracle连接 .

    所以你做的是,在你的actionPerformed:

    try {
        // login to the database
    } catch (SqlException ex) {
        if (ex.getErrorCode() == 28001) {
            // do whatever makes sense here, pop up a dialog, ask the user for the new password
        } else {
            // do whatever makes sense if you get a different error code
            throw(ex);        // for example, just let our caller handle it
        }
    }
    

    要了解在设置Oracle连接时如何指定新密码,请参阅the documentation,尤其是CONNECTION_PROPERTY_SET_NEW_PASSWORD .

    编辑:

    免责声明:我现在不在电脑上进行测试 .

    DriverManager类有各种不同的指定参数的方法 . 其中一个是 DriverManager.getConnection(String url, String user, String password) 方法,它是另一个方法, DriverManager.getConnection(String url, Properties info) 允许传递额外的,可能是数据库特定的属性 .

    使用时,您需要将用户名和密码放入属性集中:

    java.util.Properties info = new java.util.Properties();
    info.put ("user", "scott");
    info.put ("password","tiger");
    con = DriverManager.getConnection ("jdbc:oracle:oci8:@",info);
    

    现在,您可以在创建连接之前添加任何其他记录的属性:

    java.util.Properties info = new java.util.Properties();
    info.put ("user", "scott");
    info.put ("password","tiger");
    info.put (OracleDriver.CONNECTION_PROPERTY_SET_NEW_PASSWORD, "gorilla");
    con = DriverManager.getConnection ("jdbc:oracle:oci8:@",info);
    

    当您尝试登录时应该更改密码(如果旧密码正确但当然已过期) .

    我找到了一个hint on the internet,瘦驱动程序可能不支持这个,你需要本机驱动程序,但该页面没有日期戳,瘦驱动程序已经对版本11有了很大的喜爱,所以很有可能这对于瘦驱动程序来说很有用好 .

  • 0

    对于它的 Value ,从12.2开始,您可以使用JDBC-thin驱动程序使用 oracle.jdbc.newPassword 连接属性更改过期的密码 .

相关问题