使用Oracle客戶端wallet實現匿名登入

realkid4發表於2011-11-07

 

我們無論是透過Oracle客戶端的各種工具、還是應用系統連結資料庫,連結使用者名稱和密碼都是不可缺少的驗證環節。這些敏感資訊的儲存方式其實一直是一個比較糾結的問題,最常用的方法就是透過硬編碼或者配置檔案儲存的方法,這種方式具有不靈活和安全性低的缺點。

 

Oracle中可以使用wallet支援客戶端的密碼安全保證。Oracle wallet相當於一個安全容器,可以將特定資料庫連線的安全使用者名稱密碼加以儲存。這樣對系統部署結構上就存在很大的簡化空間,可以實現將安全資訊繫結在特點的客戶端機器上不至於洩露。

 

1、環境準備

 

當前系統中存在一個本地服務名otstest,連線的是遠端Oracle服務ots。

 

 

C:\Users\Liuziyu>tnsping otstest

 

TNS Ping Utility for 32-bit Windows: Version 10.2.0.1.0 - Production on 04-11月- 2011 09:09:14

 

Copyright (c) 1997, 2005, Oracle.  All rights reserved.

已使用的引數檔案:

C:\oracle\product\10.2.0\client_1\network\admin\sqlnet.ora

 

 

已使用 TNSNAMES 介面卡來解析別名

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)

(HOST = 10.1.39.93)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = ots)))

OK (30 毫秒)

 

 

此時,只能透過直接輸入使用者名稱密碼的方法實現伺服器登入。

 

 

SQL*Plus: Release 10.2.0.1.0 - Production on 星期五 11月 4 09:07:07 2011

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

 

SQL> conn scott/tiger@otstest

已連線。

SQL>

 

 

Net Service配置目錄中檔案結構如下(是客戶端目錄!),其中只有標準的三檔案(listener.ora,sqlnet.ora,tnsnames.ora)。

 

 

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>dir

 驅動器 C 中的卷沒有標籤。

 卷的序列號是 24E3-798B

 

 C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN 的目錄

 

2011/11/04  09:12   

          .

2011/11/04  09:12   

          ..

2011/09/21  15:30               470 listener.ora

2010/06/18  15:04   

          SAMPLE

2011/09/21  15:30               468 sqlnet.ora

2011/09/21  15:32             2,268 tnsnames.ora

               3 個檔案          3,206 位元組

               3 個目錄  4,123,144,192 可用位元組

 

 

 

2、建立wallet

 

預設情況下,Oracle客戶端是不會建立wallet容器的,所以需要我們手工進行建立。注意:這個也是在客戶端機器上的建立。

 

 

--建立wallet

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>mkstore -wrl C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN -create

輸入口令:

 

再次輸入口令:

 

 

在命令列中,會要求輸入並且確認密碼,這個密碼是wallet的密碼。我們在使用、修改、新增wallet物件的時候,是需要輸入這個密碼的。

 

建立之後,Net Service檔案目錄新增了一系列的檔案和資料夾。

 

 

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>dir

 驅動器 C 中的卷沒有標籤。

 卷的序列號是 24E3-798B

 

 C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN 的目錄

 

2011/11/04  09:14   

          .

2011/11/04  09:14   

          ..

2011/11/04  09:13   

          -create

2011/11/04  09:13   

          -wrl

2011/11/04  09:14             7,940 cwallet.sso

2011/11/04  09:14             7,912 ewallet.p12

2011/09/21  15:30               470 listener.ora

2010/06/18  15:04   

          SAMPLE

2011/09/21  15:30               468 sqlnet.ora

2011/09/21  15:32             2,268 tnsnames.ora

               5 個檔案         19,058 位元組

5 個目錄  4,123,086,848 可用位元組

 

 

 

3、將驗證資訊輸入到wallet中

 

建立wallet之後,我們可以將登入otstest的使用者名稱密碼儲存在wallet中。

 

 

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>mkstore -wrl C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN -createCredential OTSTEST scott tiger

輸入口令:

 

Create credential oracle.security.client.connect_string1

 

 

使用mkstore命令,將登入otstest連線的使用者名稱密碼(scott/tiger)儲存在其中。

 

這個過程中是要求輸入一個口令,注意這個口令就是我們建立wallet的時候輸入的口令。因為我們需要向其中輸入一個新的安全驗證連結,所以是要進行wallet驗證的。

 

此外,我們還要修改sqlnet.ora引數檔案,該檔案包含了驗證手段內容資訊。

 

# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\sqlnet.ora

# Generated by Oracle configuration tools.

 

# This file is actually generated by netca. But if customers choose to

# install "Software Only", this file wont exist and without the native

# authentication, they will not be able to connect to the database on NT.

 

SQLNET.AUTHENTICATION_SERVICES= (NTS)

 

NAMES.DIRECTORY_PATH= (TNSNAMES, HOSTNAME, EZCONNECT)

 

SQLNET.WALLET_OVERRIDE = TRUE

WALLET_LOCATION =

 (SOURCE=

   (METHOD = FILE)

     (METHOD_DATA = (DIRECTORY=C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN)

   )

 )

 

 

其中標紅的部分就是需要新增的內容,表示開啟wallet元件,並且告知wallet存放的預設路徑。

 

tnsnames.ora裡,不需要額外的配置。

 

 

--tnsnames.ora

OTSTEST =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.39.93)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVICE_NAME = ots)

    )

  )

 

 

 

4、Sqlplus實驗連線

 

此時,我們開啟sqlplus工具,就可以使用匿名方式登入。

 

 

--sqlplus

SQL*Plus: Release 10.2.0.1.0 - Production on 星期五 11月 4 09:24:03 2011

 

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

 

SQL> conn /@otstest

已連線。

 

SQL> set wrap off;

SQL> select instance_name, host_name from v$instance;

 

INSTANCE_NAME    HOST_NAME

---------------- ---------------------------------------------------

ots              AAAA-119HS63YXC

 

 

登入時的連線使用者,就是我們設定的scott/tiger使用者名稱密碼。該資訊被儲存在wallet中。

 

 

5、JDBC匿名連線

 

筆者認為,匿名登入最大的優勢就是應用系統不需要儲存登入使用者名稱密碼,而是依賴特定的客戶端伺服器。在Java中,我們可以如下書寫:

 

 

--JDBC

import java.sql.*;

import oracle.jdbc.OracleDriver;

 

public class JavaTest {

 

    public static Connection getConnection() throws SQLException {

        DriverManager.registerDriver(new OracleDriver());

        Connection conn = DriverManager

                .getConnection("jdbc:oracle:oci:/@otstest");

        conn.setAutoCommit(false);

        return conn;

    }

 

    public void run() throws SQLException {

        Connection conn = getConnection();

        // Create a Statement

        Statement stmt = conn.createStatement();

        // Select the ENAME column from the EMP table

        ResultSet rset = stmt.executeQuery("select ENAME from EMP");

        // Iterate through the result and print the employee names

        while (rset.next())

            System.out.println(rset.getString(1));

        // Close the RseultSet

        rset.close();

        // Close the Statement

        stmt.close();

        // Close the connection

        conn.close();

    }

 

    /**

     * @param args

     */

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        try {

            JavaTest test = new JavaTest();

            test.run();

        } catch (SQLException ex) {

            ex.printStackTrace();

        }

    }

}

 

 

程式碼裡面只需要輸入連線“jdbc:oracle:oci:/@otstest”,就可以實現訪問。

 

這裡有一個注意的方面:JDBC使用的驅動一定要和客戶端Oracle版本相同,比如客戶端是使用10g客戶端,對應的JDBC也一定要使用10g版本的JDBC。否則會報OCI版本錯誤,如下:

 

 

Exception in thread "main" java.lang.UnsatisfiedLinkError: no ocijdbc11 in java.library.path

    at java.lang.ClassLoader.loadLibrary(Unknown Source)

    at java.lang.Runtime.loadLibrary0(Unknown Source)

    at java.lang.System.loadLibrary(Unknown Source)

    at oracle.jdbc.driver.T2CConnection$1.run(T2CConnection.java:3506)

    at java.security.AccessController.doPrivileged(Native Method)

    at oracle.jdbc.driver.T2CConnection.loadNativeLibrary(T2CConnection.java:3502)

    at oracle.jdbc.driver.T2CConnection.logon(T2CConnection.java:252)

    at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:531)

    at oracle.jdbc.driver.T2CConnection.(T2CConnection.java:148)

    at oracle.jdbc.driver.T2CDriverExtension.getConnection(T2CDriverExtension.java:53)

    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503)

    at java.sql.DriverManager.getConnection(Unknown Source)

    at java.sql.DriverManager.getConnection(Unknown Source)

    at com.acca.test.JavaTest.getConnection(JavaTest.java:21)

    at com.acca.test.JavaTest.run(JavaTest.java:28)

    at com.acca.test.JavaTest.main(JavaTest.java:57)

 

 

6、結論

 

使用wallet方式進行資料庫使用者名稱密碼儲存,可以有效的減少資料庫密碼洩露的可能性,也可以保證應用系統在特定的部署結構上生效。具有相當強的實用性。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-710397/,如需轉載,請註明出處,否則將追究法律責任。

相關文章