zoukankan      html  css  js  c++  java
  • 使用JDBC实现Oracle用户认证

    两天时间写的小品,以前的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 table
    create 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的框架中完成对比,个人更喜欢把这些工作交给数据库去完成,可以节省资源。

  • 相关阅读:
    1105 Spiral Matrix (25分)(蛇形填数)
    1104 Sum of Number Segments (20分)(long double)
    1026 Table Tennis (30分)(模拟)
    1091 Acute Stroke (30分)(bfs,连通块个数统计)
    1095 Cars on Campus (30分)(排序)
    1098 Insertion or Heap Sort (25分)(堆排序和插入排序)
    堆以及堆排序详解
    1089 Insert or Merge (25分)
    1088 Rational Arithmetic (20分)(模拟)
    1086 Tree Traversals Again (25分)(树的重构与遍历)
  • 原文地址:https://www.cnblogs.com/learnhow/p/6251562.html
Copyright © 2011-2022 走看看