標籤:crypto oracle 方便 span null for 返回 ati tmp
兩天時間寫的小品,以前的J2EE環境基本使用架構。現在使用JDBC配合Oracle預存程序類比了一下使用者註冊和使用者認證。
一、添加必須的jar包
需要JDBC串連Oracle的包和shiro-core依賴,添加shiro-core主要為了方便使用SHA-256散列演算法。
二、編寫JDBC串連
import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class Oracle { private static final Logger logger = LoggerFactory.getLogger(Oracle.class); public static Connection getConnection() { Connection conn = null; try { Class.forName("oracle.jdbc.driver.OracleDriver"); logger.debug("嘗試串連資料庫"); String url = "jdbc:oracle:thin:@192.168.0.20:1541:test"; String username = "apps"; String password = "apps"; conn = DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException cnfe) { logger.error(cnfe.getMessage()); } catch (SQLException sqle) { logger.error(sqle.getMessage()); } return conn; } public static void closeConnection(Connection conn) { try { if (conn != null) { conn.close(); conn = null; } } catch (SQLException sqle) { logger.error(sqle.getMessage()); } }}
三、建表
-- Create tablecreate table LH_USER_T( id INTEGER not null, username VARCHAR2(255), -- 使用者名稱 password VARCHAR2(255), -- 密碼 roleid INTEGER -- 外鍵連結)
完整的使用者添加和認證授權應該至少包含三張表:user_table、role_table和permission_table,本文不展開討論。
四、添加使用者
UserDao類負責資料庫通訊,密碼散列由UserService類實現。
import java.sql.CallableStatement;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.Types;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class UserDao { private static final Logger logger = LoggerFactory.getLogger(UserDao.class); // 添加使用者 public void saveUser(int userid, String username, String password, int roleid) { String sql = "insert into lh_user_t values (?,?,?,?)"; Connection conn = Oracle.getConnection(); PreparedStatement ps = null; try { ps = conn.prepareStatement(sql); ps.setInt(1, userid); ps.setString(2, username); ps.setString(3, password); ps.setInt(4, roleid); ps.executeUpdate(); } catch (SQLException sqle) { logger.error(sqle.getMessage()); } finally { Oracle.closeConnection(conn); if (ps != null) { try { ps.close(); } catch (SQLException e) { logger.error(e.getMessage()); } ps = null; } } } // 驗證使用者(後面添加)}
UserService類
import org.apache.shiro.crypto.hash.Sha256Hash;public class UserService { private UserDao userDao; private static int userid = 1; public UserService() { userDao = new UserDao(); } public void saveUser(String username, String password, int roleid) { String nPassword = new Sha256Hash(password).toHex(); userDao.saveUser(UserService.userid, username, nPassword, roleid); } //...}
五、使用者驗證(Oracle預存程序)
create or replace procedure validate_user(in_username in varchar2, in_password in varchar2, out_result out varchar2) as tmp_uid lh_user_t.id%type;begin select count(*) into tmp_uid from lh_user_t t where t.username = in_username and t.password = in_password; out_result := ‘S‘;exception when NO_DATA_FOUND then out_result := ‘E‘;end;
六、使用者驗證(JDBC調用預存程序)
import java.sql.CallableStatement;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import java.sql.Types;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class UserDao { private static final Logger logger = LoggerFactory.getLogger(UserDao.class); // 添加使用者 // {...} // 驗證使用者 public String validateUser(String username, String password) { String sql = "call validate_user(?,?,?)"; String result = null; Connection conn = Oracle.getConnection(); CallableStatement cs = null; try { cs = conn.prepareCall(sql); cs.setString(1, username); cs.setString(2, password); cs.registerOutParameter(3, Types.VARCHAR); cs.execute(); result = cs.getString(3); } catch (SQLException sqle) { logger.error(sqle.getMessage()); } finally { Oracle.closeConnection(conn); if (cs != null) { try { cs.close(); } catch (SQLException e) { logger.error(e.getMessage()); } cs = null; } } return result; }}
下面還需要在UserService類中添加散列演算法
public class UserService { private UserDao userDao; private static int userid = 1; public UserService() { userDao = new UserDao(); } // {...} public String validateUser(String username, String password) { String nPassword = new Sha256Hash(password).toHex(); return userDao.validateUser(username, nPassword); }}
七、總結
應用程式層根據service類返回的字串判斷使用者是否認證成功,‘E‘ 代表失敗,‘S‘ 代表成功。使用任何驗證架構都需要從資料庫中讀取使用者密碼並在Java的架構中完成對比,個人更喜歡把這些工作交給資料庫去完成,可以節省資源。
使用JDBC實現Oracle使用者認證