Commit dde084f5 by 郑冰晶

优化异常告警

parent 6b608d56
......@@ -8,17 +8,17 @@ import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.util.Utils;
import com.secoo.mall.datasource.security.algorithm.encrypt.AESEncryptAlgorithm;
import com.secoo.mall.datasource.security.exception.SecurityBizException;
import com.secoo.mall.datasource.security.rule.ColumnRule;
import com.secoo.mall.datasource.security.rule.DbRule;
......@@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory;
import java.io.Reader;
import java.io.StringReader;
import java.security.GeneralSecurityException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
......@@ -338,74 +337,104 @@ public class SecurityFilter extends FilterEventAdapter {
stmt.accept(visitor);
int index = 0;
// 查询 | 删除
// 查询 | 删除(where)
if (stmt instanceof SQLSelectStatement || stmt instanceof MySqlDeleteStatement) {
// 查询条件
for (TableStat.Condition condition : visitor.getConditions()) {
// 查询条件值,in/between语句等可能有多个
for (Object conditionValue : condition.getValues()) {
// 解析出条件值为空为查询条件
if (conditionValue != null) {
if (conditionValue != null) {// ?
continue;
}
int parameterIndex = index ++;
TableStat.Column column = condition.getColumn();
Map<String, ColumnRule> columnRuleMap = this.getTableRuleMap().get(column.getTable());
if (columnRuleMap != null && !columnRuleMap.isEmpty()) {
// 需要加密的字段
ColumnRule columnRule = columnRuleMap.get(column.getName());
if (columnRule != null) {
encrypt(columnRule, preparedStatement, index);
}
if (columnRuleMap == null || columnRuleMap.isEmpty()) {
continue;
}
ColumnRule columnRule = columnRuleMap.get(column.getName());
if (columnRule == null) {
continue;
}
index ++;
encrypt(columnRule, preparedStatement, parameterIndex);
}
}
}
// 插入
// 插入(单条 || 批量、values)
else if (stmt instanceof MySqlInsertStatement) {
MySqlInsertStatement insertStmt = (MySqlInsertStatement) stmt;
String tableName = insertStmt.getTableName().getSimpleName();
Map<String, ColumnRule> columnRuleMap = this.getTableRuleMap().get(tableName);
if (columnRuleMap != null && !columnRuleMap.isEmpty()) {
int valuesSize = insertStmt.getValuesList().size();
Collection<TableStat.Column> columns = visitor.getColumns();
int columnSize = columns.size();
for (TableStat.Column column : columns) {
// 需要加密的字段
ColumnRule columnRule = columnRuleMap.get(column.getName());
if (columnRule != null) {
for (int valueIndex = 0; valueIndex < valuesSize; valueIndex++) {
encrypt(columnRule, preparedStatement, index + valueIndex * columnSize);
List<TableStat.Column> columnList = new ArrayList<>(columns);
if(!columnList.isEmpty()){// 插入sql不能省略列名
List<SQLInsertStatement.ValuesClause> valuesClauses = insertStmt.getValuesList();
int valuesSize = insertStmt.getValuesList().size();
for(SQLInsertStatement.ValuesClause valuesClause:valuesClauses){
List<SQLExpr> values = valuesClause.getValues();
for(int columnIndex=0; columnIndex < values.size();columnIndex++){
SQLExpr value = values.get(columnIndex);
if (!(value instanceof SQLVariantRefExpr)) {// ?
continue;
}
int parameterIndex = index ++;
TableStat.Column column = columnList.get(columnIndex);
ColumnRule columnRule = columnRuleMap.get(column.getName());
if (columnRule != null) {
for (int valueIndex = 0; valueIndex < valuesSize; valueIndex++) {
encrypt(columnRule, preparedStatement, parameterIndex);
}
}
}
}
}
}
index ++;
}
// 更新
// 更新(单条 || 批量、set、where)
else if (stmt instanceof MySqlUpdateStatement) {
MySqlUpdateStatement updateStmt = (MySqlUpdateStatement) stmt;
// 更新语句应该只支持单表
String tableName = updateStmt.getTableName().getSimpleName();
Map<String, ColumnRule> columnRuleMap = this.getTableRuleMap().get(tableName);
if (columnRuleMap == null || columnRuleMap.isEmpty()) {
continue;
}
// 处理set
for (SQLUpdateSetItem item : updateStmt.getItems()) {
SQLExpr column = item.getColumn();
if (item.getValue() instanceof SQLVariantRefExpr && column instanceof SQLIdentifierExpr) {
// 需要加密的字段
String columnName = ((SQLIdentifierExpr) column).getName();
ColumnRule columnRule = columnRuleMap.get(columnName);
if (columnRule != null) {
encrypt(columnRule, preparedStatement,index);
SQLExpr value = item.getColumn();
if (!(value instanceof SQLVariantRefExpr)) {
continue;
}
int parameterIndex = index ++;
String tableName = null;
String columnName = null;
if(column instanceof SQLIdentifierExpr){// name = ?
SQLIdentifierExpr sqlIdentifierExpr = (SQLIdentifierExpr) column;
tableName = sqlIdentifierExpr.getResolvedOwnerObject().toString();
columnName = sqlIdentifierExpr.getName();
}else if(column instanceof SQLPropertyExpr){// a.name = ? 或 t_user.name = ? 或 secooAbcDB.t_user.name = ?(不考虑)
SQLPropertyExpr sqlPropertyExpr = (SQLPropertyExpr) column;
if(sqlPropertyExpr.getResolvedOwnerObject() != null){
tableName = sqlPropertyExpr.getResolvedOwnerObject().toString();
columnName = sqlPropertyExpr.getName();
}
}
index++;
if(tableName == null || columnName == null){
continue;
}
Map<String, ColumnRule> columnRuleMap = this.getTableRuleMap().get(tableName);
if (columnRuleMap == null || columnRuleMap.isEmpty()) {
continue;
}
ColumnRule columnRule = columnRuleMap.get(columnName);
if (columnRule == null) {
continue;
}
encrypt(columnRule, preparedStatement,parameterIndex);
}
// 处理where
......@@ -416,29 +445,23 @@ public class SecurityFilter extends FilterEventAdapter {
if (conditionValue == null) {
continue;
}
int parameterIndex = index ++;
TableStat.Column column = condition.getColumn();
Map<String, ColumnRule> columnRuleMap = this.getTableRuleMap().get(column.getTable());
if (columnRuleMap == null || columnRuleMap.isEmpty()) {
continue;
}
ColumnRule columnRule = columnRuleMap.get(column.getName());
if (columnRule != null) {
encrypt(columnRule, preparedStatement,index);
encrypt(columnRule, preparedStatement,parameterIndex);
}
index++;
}
}
}
// 其他
else {
for (TableStat.Column column : visitor.getColumns()) {
Map<String, ColumnRule> columnRuleMap = this.getTableRuleMap().get(column.getTable());
if (columnRuleMap != null && !columnRuleMap.isEmpty()) {
// 需要加密的字段
ColumnRule columnRule = columnRuleMap.get(column.getName());
if (columnRule != null) {
encrypt(columnRule, preparedStatement,index);
}
}
index++;
}
log.warn("This sql type is not support to security !!! sql = {}",sql);
}
}
}
......@@ -509,28 +532,4 @@ public class SecurityFilter extends FilterEventAdapter {
this.tableRuleMap = tableRuleMap;
}
public static void main(String[] args) {
String sql = "update t_user u,t_account a set u.name=?,a.age=10 where u.id = a.id and u.id > 12 and a.age >?";
// 解析sql
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql,"mysql");
for (SQLStatement stmt : stmtList) {
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
stmt.accept(visitor);
SQLUpdateStatement _stmt = (SQLUpdateStatement) stmt;
System.out.println(visitor.getColumns());
System.out.println(_stmt.getItems());
}
String cipherText = "定时任务";
AESEncryptAlgorithm aesEncryptAlgorithm = new AESEncryptAlgorithm();
aesEncryptAlgorithm.getProps().setProperty(AESEncryptAlgorithm.ENCRYPT_KEY,"123");
aesEncryptAlgorithm.init();
try {
aesEncryptAlgorithm.decrypt(cipherText);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
System.out.println("");
}
}
package com.secoo.mall.datasource.security.visitor;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter;
public class ParameterVisitor extends MySqlASTVisitorAdapter {
}
package com.secoo.mall.datasource.security;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.secoo.mall.datasource.security.rule.ColumnRule;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class SQLParserTest {
public static void testVisitor(){
// String sql = "select u.name,a.age from t_user u,t_account a where u.id = a.id and t_account.id > 12 and a.age >?;";
// String sql = "select secooStoreDB.t_sequence.`code` from secooStoreDB.t_sequence,secooStoreDB.t_store_fail_mq where secooStoreDB.t_sequence.`code`=secooStoreDB.t_store_fail_mq.topic";
// String sql = "delete from t_sequence";
// String sql = "INSERT INTO `secooStoreDB`.`t_sequence`(`t_sequence`.`name`, `current_value`, `increment`, `code`) VALUES (?, 4551, 1, 2),('t_store_category', 65015, 1, 1);";
// String sql = "INSERT INTO `secooStoreDB`.`t_sequence` VALUES ('t_store', 4551, 1, 2),('t_store_category', 65015, 1, 1)";
// String sql = "update t_user set name=?,age=10 where id = id and id > 12";
// String sql = "update t_user u,t_account a set u.name=?,a.age=10 where u.id = a.id and u.id > 12 and a.age >?";
// String sql = "update t_user u,t_account a set t_user.name=?,a.age=10 where u.id = a.id and u.id > 12 and a.age >?";
String sql = "update t_user u,t_account a set secooStoreDB.t_account.name=?,a.age=10 where secooStoreDB.t_account.id = a.id and u.id > 12 and a.age >?";
// 解析sql
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql,"mysql");
for (SQLStatement stmt : stmtList) {
MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
stmt.accept(visitor);
System.out.println(visitor.getParameters());
if (stmt instanceof SQLSelectStatement) {
SQLSelectStatement selectStmt = (SQLSelectStatement) stmt;
System.out.println(visitor.getColumns());
System.out.println(selectStmt.getSelect());
System.out.println("---");
}else if(stmt instanceof MySqlDeleteStatement){
MySqlDeleteStatement deleteStmt = (MySqlDeleteStatement) stmt;
System.out.println("---");
}else if (stmt instanceof MySqlInsertStatement) {
MySqlInsertStatement insertStmt = (MySqlInsertStatement) stmt;
String tableName = insertStmt.getTableName().getSimpleName();
int valuesSize = insertStmt.getValuesList().size();
Collection<TableStat.Column> columns = visitor.getColumns();
int columnSize = columns.size();
for (TableStat.Column column : columns) {
System.out.println(column.getTable());
}
System.out.println("---");
}else if(stmt instanceof MySqlUpdateStatement){
MySqlUpdateStatement updateStmt = (MySqlUpdateStatement) stmt;
for(SQLUpdateSetItem item :updateStmt.getItems()){
if (item.getValue() instanceof SQLVariantRefExpr) {
SQLVariantRefExpr sqlVariantRefExpr = (SQLVariantRefExpr) item.getValue();
if(item.getColumn() instanceof SQLIdentifierExpr){
SQLIdentifierExpr sqlIdentifierExpr = (SQLIdentifierExpr) item.getColumn();
System.out.println(sqlIdentifierExpr.getResolvedOwnerObject().toString());
}else if(item.getColumn() instanceof SQLPropertyExpr){
SQLPropertyExpr columnSqlPropertyExpr = (SQLPropertyExpr) item.getColumn();
if(columnSqlPropertyExpr.getOwner() instanceof SQLIdentifierExpr){
SQLIdentifierExpr tableSQLIdentifierExpr = (SQLIdentifierExpr) columnSqlPropertyExpr.getOwner();
System.out.println(tableSQLIdentifierExpr.getName());
System.out.println(columnSqlPropertyExpr.getResolvedOwnerObject().toString());
}else{
SQLPropertyExpr tableSqlPropertyExpr = (SQLPropertyExpr) columnSqlPropertyExpr.getOwner();
System.out.println(tableSqlPropertyExpr.getName());
}
}
}
}
System.out.println("---");
}else{
}
}
/*String cipherText = "定时任务";
AESEncryptAlgorithm aesEncryptAlgorithm = new AESEncryptAlgorithm();
aesEncryptAlgorithm.getProps().setProperty(AESEncryptAlgorithm.ENCRYPT_KEY,"123");
aesEncryptAlgorithm.init();
try {
aesEncryptAlgorithm.decrypt(cipherText);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
System.out.println("");*/
}
public static void main(String[] args) {
testVisitor();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment