纯css打造立体时钟
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
By_jie

jdbc_012_使用jdbc操作实现登录操作并且演示SQL注入攻击

一、建库及表语句(简单测试)

drop database db_test;
create database db_test;
use db_test;
create table user(
    userId int(5) primary key comment '用户id',
    userName varchar(16) comment '用户姓名',
    userPw varchar(16) comment '用户密码'
);
insert into user(userId,userName,userPw) values(10001,'user1','user1');
insert into user(userId,userName,userPw) values(10002,'user2','user2');
insert into user(userId,userName,userPw) values(10003,'user3','user3');
insert into user(userId,userName,userPw) values(10004,'user4','user4');
insert into user(userId,userName,userPw) values(10005,'user5','user5');

二、封装jdbc的工具类(同上集)

package edu.aeon.aeonutils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * [说明]:jdbc工具类
 * 封装了jdbc里面的重复步骤:数据库的连接和数据库资源的释放
 * @author aeon
 * @version 1.2(该版本将连接数据库的各种数据库配置信息(用户名、密码、驱动及url)单独提取到配置文件中)
 */
public class AeonJdbcUtils {
    private static String username;
    private static String password;
    private static String driverClass;
    private static String url;
    /**
     * 静态代码块处理读取之前的数据
     */
    static{
        InputStream inputStream = AeonJdbcUtils.class.getClassLoader().getResourceAsStream("config/database/database.properties");
        Properties properties=new Properties();
        try {
            properties.load(inputStream);
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            driverClass = properties.getProperty("driverClass");
            url = properties.getProperty("url");
        } catch (IOException e) {
            System.out.println("初始化读取数据库配置文件--->database.properties失败!");
            e.printStackTrace();
        }finally{
     //关闭流
    } }
/** * 连接数据库 * @return 数据库连接对象 * @throws ClassNotFoundException * @throws SQLException */ public static Connection getMySqlConnection() throws ClassNotFoundException, SQLException{ Class.forName(driverClass); return DriverManager.getConnection(url, username, password); } /** * 释放数据库资源 * @param resultSet 结果集 * @param statement 执行sql语句的对象 * @param connection 数据库连接对象 */ public static void closeDB(ResultSet resultSet,Statement statement,Connection connection){ if(null!=resultSet){ try { resultSet.close(); } catch (SQLException e) { System.out.println("释放数据库资源失败!--->resultSet"); e.printStackTrace(); } } if(null!=statement){ try { statement.close(); } catch (SQLException e) { System.out.println("释放数据库资源失败!--->statement"); e.printStackTrace(); } } if(null!=connection){ try { connection.close(); } catch (SQLException e) { System.out.println("释放数据库资源失败!--->connection"); e.printStackTrace(); } } } }

三、包视图截图:

  

四、数据库配置信息database.properties  

 username=root
 password=root
 driverClass=com.mysql.jdbc.Driver
 url=jdbc:mysql://localhost:3306/db_test

五、数据库截图信息:

  

 

六、用户登录

package edu.aeon.logon;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import edu.aeon.aeonutils.AeonJdbcUtils;
/**
 * [说明]:实现用户登录、并且演示sql注入攻击
 * 造成sql注入攻击的原因
 *     1.and和or的优先级(and(可以理解为并且)优先与or(可以理解为或者))其实是构造or的条件来无视and条件()
 *     2.sql语句的拼接
 * 如何解决sql注入攻击?
 *     数据库and 和 or的优先级天生的、我们无法改变
 *     唯一解决思路:改变sql语句的拼接、(详见下集)
 * @author aeon
 *
 */
public class UserLogon {
    /**
     * 封装键盘输入
     * @return
     */
    public static Map<String, String> ReadBoard(){
        /**
         * 键盘扫描器:扫描键盘输入的内容
         */
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username=scanner.nextLine();//以\n作为一行的标识来读取一行
        System.out.println("请输入密码:");
        String password=scanner.nextLine();
        Map<String, String> userMap=new HashMap<String, String>();
        //将键盘输入的内容封装到map集合中、并且返回给调用者
        userMap.put("username", username);
        userMap.put("password", password);
        return userMap;
    }
    /**
     * 用户登录具体实现
     * @return 登录成功标志 true则登录成功、否则失败!
     */
    public static boolean userLogon(){
        boolean flag=false;
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            //连接数据库
            connection = AeonJdbcUtils.getMySqlConnection();
            //获得执行sql语句对象
            statement = connection.createStatement();
            //获取到用户输入的数据
            Map<String, String> userMap=ReadBoard();
            //登录sql
            String logonSql="select * from user where username='"+userMap.get("username")+"' and userpw ='"+userMap.get("password")+"'";
            System.out.println("登录的sql语句为:"+logonSql);
            resultSet = statement.executeQuery(logonSql);
            if(resultSet.next()){ //如果数据库中有记录则将登录标志flag置为true
                flag = true;
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
      AeonJdbcUtils.closeDB(resultSet, statement, connection);

   }

return flag;
    }
    /**
     * 用户登录测试
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(userLogon()?"用户登录成功!":"用户登录失败!");
    }
}

 执行结果截图(我们输入数据库中根本不存在的用户和密码):

  

 执行结果截图(我们输入数据库中存在的用户和其对应密码):

  

执行结果截图(构造sql注入攻击):

  

 用or来使的前面and条件无效、其实这条sql攻击语句最后执行等同于:select * from user where 'x'='x'

我们可以看出where条件永远为真。实则和select * from user;效果无疑!

posted @ 2018-12-05 21:57  1024军团  阅读(432)  评论(0编辑  收藏  举报