package com.jiayue.ssi.filter;

import com.jiayue.ssi.util.IPUtils;
import com.jiayue.ssi.util.ResponseInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

/**
* 防sql注入
*
* @author xsl
* @since 2023/05/19
*/
@RequiredArgsConstructor
@Order(9)
@Slf4j
public class SqlFilter  extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获得所有请求参数名
        Enumeration<String> names = request.getParameterNames();
        while (names.hasMoreElements()){
            //得到参数名
            String name = names.nextElement().toString();
            //得到参数对应值
            String[] values = request.getParameterValues(name);
            for (int i = 0; i < values.length; i++) {
                if (sqlValidate(values[i])){
                    ResponseInfo.doResponse(response, "请求中的参数中含有非法字符！", 401);
                    return;
                }
            }
        }
        filterChain.doFilter(request,response);
    }
    //效验
    protected static boolean sqlValidate(String str){
        String s = str.toLowerCase();//统一转为小写
        String badStr =
                "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|table|"+
                        "char|declare|sitename|xp_cmdshell|like|from|grant|use|group_concat|column_name|" +
                        "information_schema.columns|table_schema|union|where|order|by|" +
                        "'\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#";//过滤掉的sql关键字，特殊字符前面需要加\\进行转义
        String regx = ".*(\\b(exec|execute|insert|into|create|drop|table|from|grant|group_concat|column_name|" +
                "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|" +
                "chr|mid|master|truncate|char|declare|or|like)\\b).*";
        //使用正则表达式进行匹配
        boolean matches = s.matches(regx);
        return matches;
    }
}
