Обработка истечения срока действия пароля Oracle и льготного периода с использованием Java, Oracle JDBC

У меня есть база данных Oracle 11g, и я написал приложение, которое наряду со многими другими вещами может создавать пользователей. я хочу, чтобы конечный пользователь, который использует учетную запись, изменил пароль после создания, поэтому я установил предложение pasword expire при создании пользователя.

Итак, теперь мой вопрос заключается в том, как обрабатывать исключение ORA-28001: the password has expired в java, чтобы пользователь мог изменить пароль по мере необходимости. 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;
}

после этого я получаю тот же вывод ошибки, что и раньше

РЕДАКТИРОВАТЬ СНОВА:

ну, я думал, что он у меня есть, но нет, все-таки не сработало, ни поле + новый пароль, ни значение поля + новый пароль не работали с этим URL: 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);

person PeterYoshi    schedule 12.02.2014    source источник
comment
я немного почитаю о тонком и толстом в настоящее время, я думаю, что получу ответ, который мне нужен, во время исследования, большое спасибо.   -  person PeterYoshi    schedule 13.02.2014


Ответы (3)


Было бы полезно, если бы вы разместили код. Стек намекает на свинг-приложение, которое запускает соединение с оракулом при нажатии кнопки.

Итак, что вы делаете, в вашем 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, см. документация, особенно 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);

который должен изменить пароль при попытке входа в систему (при условии, что старый правильный, но, конечно, срок его действия истек).

Я нашел намек в Интернете, что тонкий драйвер может не поддерживать это, и вам нужен родной драйвер, но на этой странице нет метки даты, а тонкий драйвер получил большую популярность в версии 11, поэтому велика вероятность, что это работает и с тонким драйвером.

person Guntram Blohm    schedule 12.02.2014
comment
пока спасибо, подсказывает, что делать, я дополнительно опубликовал свой метод opencon() - person PeterYoshi; 12.02.2014
comment
можете ли вы сказать мне, как указать новый пароль, информация, найденная по ссылке, которую вы разместили, действительно тонкая (ха-ха), и я не мог понять, как на самом деле установить новый пароль - person PeterYoshi; 12.02.2014
comment
стоит попробовать, и большое спасибо за быстрый ответ, но срок действия пароля все еще истекает, когда я пытался восстановить - person PeterYoshi; 13.02.2014
comment
Хорошо. Другая ссылка (community.oracle.com/message/10607895), кажется, подтверждает это. драйвер oci и не работает с тонким драйвером. (Упомянутый OciNewPassword имеет значение CONNECTION_PROPERTY_SET_NEW_PASSWORD, так что все должно быть в порядке). Но если вы используете драйвер OCI (в вашем URL-адресе есть oci, а не тонкий, между 2-м и 3-м двоеточием), и он все еще не работает, я в замешательстве. - person Guntram Blohm; 13.02.2014
comment
согласно этой ветке он ДОЛЖЕН работать с тонким драйвером. как говорит rp0428, мне нужно только изменить третье значение реквизита с CONNECTION_PROPERTY_SET_NEW_PASSWORD на его значение OciNewPassword. я сейчас на работе, но я попробую это, когда вернусь домой, спасибо, чувак, наконец-то это может быть :D - person PeterYoshi; 13.02.2014
comment
и это всегда был мой URL-адрес: jdbc:oracle:thin...blabla.. поэтому мне просто нужно изменить имя поля на его значение в опоре - person PeterYoshi; 13.02.2014

Что бы это ни стоило, начиная с версии 12.2 вы можете использовать драйвер JDBC-thin для изменения пароля с истекшим сроком действия, используя свойство подключения oracle.jdbc.newPassword.

person Jean de Lavarene    schedule 06.05.2017

// вот пример кода для изменения пароля с истекшим сроком действия с помощью тонкого драйвера 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();
person Mike B    schedule 27.02.2018