企業級應用常面臨審計需求:資料庫端必須記錄「哪位前端登入用戶執行了什麼 SQL」。但應用通常共用單一資料庫帳號連線,導致用戶身份無法傳遞至資料庫層。本文介紹輕量級方案:透過資料庫連線攜帶用戶標識,在資料庫端完成審計。
ClientUser 等屬性)java.sql.Connection 新增:
void setClientInfo(String name, String value)
void setClientInfo(Properties properties)
支援屬性:ApplicationName、ClientUser(前端用戶 ID)、ClientHostname。常用模式:
Connection conn = getConnection();
conn.setClientInfo("ClientUser", currentUserId);
// do something
conn.setClientInfo("ClientUser", null); // 清除
conn.close();
com.ibm.db2.jcc.DB2Connection)conn.setDB2ClientUser("loginUser");
// 操作...
conn.setDB2ClientUser(null);
查看命令:db2 get snapshot for applications on databasealias(開放平台)或 -DISPLAY THREAD(*) DETAIL(z/OS)。
oracle.jdbc.driver.OracleConnection)conn.setClientIdentifier(clientId);
// 操作...
conn.clearClientIdentifier(clientId);
資料庫端查詢:SELECT client_identifier FROM v$session。開啟審計:AUDIT SELECT TABLE BY SESSION,再查 DBA_AUDIT_TRAIL 獲取 SQL 文本。
com.ibm.websphere.rsadapter.WSConnection)WSConnection wsconn = (WSConnection) conn;
Properties props = new Properties();
props.setProperty(WSConnection.CLIENT_ID, clientId);
wsconn.setClientInformation(props);
// 操作...
wsconn.setClientInformation(null);
支援屬性:CLIENT_ID、CLIENT_APPLICATION_NAME、CLIENT_ACCOUNTING_INFO 等。
自訂 SqlMapClient 實作,在各方法中手動取得連線、設定標識、開啟 Session、提交/回滾、清除標識。再透過 Wrapper 類暴露增強後的實例。
在事務開啟後透過 session.connection() 取得底層連線,轉型為廠商特定類型(OracleConnection/DB2Connection),設定/清除標識:
tx = sess.beginTransaction();
conn = sess.connection();
OracleConnection oraconn = (OracleConnection) conn;
oraconn.setClientIdentifier(clientId);
// do work
oraconn.clearClientIdentifier(clientId);
tx.commit();
本方案源自真實客戶場景,涵蓋 JDBC 4.0 標準、主流資料庫廠商擴展、應用服務器包裝連線、主流 ORM 框架整合四大場景,提供可直接落地的程式碼範例,助力滿足合規審計需求。