YiDunAntiFraudUtil.java 18.8 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
package com.cnlive.shenhe.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cnlive.shenhe.enums.ImageLabels;
import com.cnlive.shenhe.enums.TextLabels;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * 网易易盾
 *
 * @Author: xujincheng
 * @Date: 2020/3/18 12:47
 */
public class YiDunAntiFraudUtil {

    private static Logger logger = LoggerFactory.getLogger(YiDunAntiFraudUtil.class);

    /**
     * 网站地址URL产品密钥ID,产品标识
     */
    private final static String SECRETID = "c7f33c191020bcc9cbacb7d70417fd2f";
    /**
     * 网站地址URL产品私有密钥,服务端生成签名信息使用,请严格保管,避免泄露
     */
    private final static String SECRETKEY = "833222b4951a67a9bc63b5ed0c24d07d";

    /**
     * 文本识别 图片识别 点播音频识别产品密钥ID,产品标识
     */
    private final static String TEXTANDIMAGESECRETID = "11c62726ba11f03f3f7d87acbe2d4f03";

    /**
     * 文本识别 图片识别 点播音频识别产品私有密钥,服务端生成签名信息使用,请严格保管,避免泄露
     */
    private final static String TEXTANDIMAGESECRETKEY = "3c0d0d44909926f46e79d3518e7dc4e7";
    /**
     * 业务ID,易盾根据产品业务特点分配(文本)
     */
    private final static String TEXTBUSINESSID = "719926f98dc5b9bb9857e1b799ea3f5f";

    /**
     * 业务ID,易盾根据产品业务特点分配(图片)
     */
    private final static String IMAGEBUSINESSID = "f84d6ee9f62274243825d3e969ca4c5a";

    /**
     * 业务ID,易盾根据产品业务特点分配(点播音频)
     */
    private final static String AUDIOONDEMANDBUSINESSID = "1b77454593bf55607e3e7120d02c6389";
    /**
     * 网站地址URL提交接口地址
     * http://as.dun.163.com/v2/crawler/submit
     */
    private final static String URL_SUBMIT = "https://as.dun.163yun.com/v1/crawler/submit";

    /**
     * 点播音频地址URL提交接口地址
     */
    private final static String AUDIOONDEMAND_URL_SUBMIT = "http://as.dun.163.com/v3/audio/submit";

    /**
     * 易盾内容安全文本在线检测接口地址
     */
    private final static String TEXT_RESULT = "https://as.dun.163yun.com/v3/text/check";

    /**
     * 易盾内容安全服务图片在线检测接口地址
     */
    private final static String IMAGE_RESULT = "https://as.dun.163yun.com/v4/image/check";

    /**
     * 网站地址URL检测结果获取接口地址
     */
    private final static String URL_RESULT = "https://as.dun.163yun.com/v1/crawler/callback/results";


    /**
     * 点播音频地址提交
     *
     * @param url
     * @return
     */
    public static JSONObject submitAudioOnDemandUrl(String url, String callbackUrl) {
        try {
            Map<String, String> params = new HashMap<>();
            // 1.设置公共参数
            params.put("secretId", TEXTANDIMAGESECRETID);
            params.put("businessId", AUDIOONDEMANDBUSINESSID);
            params.put("version", "v3.1");
            params.put("timestamp", String.valueOf(System.currentTimeMillis()));
            params.put("nonce", String.valueOf(new Random().nextInt()));

            // 2.设置私有参数
            params.put("url", url);
            params.put("callbackUrl", callbackUrl);

            // 3.生成签名信息
            String signature = YiDunAntiFraudUtil.genSignature(TEXTANDIMAGESECRETKEY, params);
            params.put("signature", signature);

            // 4.发送HTTP请求,这里使用的是HttpClient工具包,产品可自行选择自己熟悉的工具包发送请求
            String s = HttpClientUtils.post_str(AUDIOONDEMAND_URL_SUBMIT, params);
            logger.info("向易盾提交点播音频检测地址返回的结果:{}", s);

            JSONObject jsonObject = JSONObject.parseObject(s);
            int code = jsonObject.getIntValue("code");
            String msg = jsonObject.getString("msg");
            if (code == 200 && "ok".equals(msg)) {
                return jsonObject;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 智能文本审核
     *
     * @param text
     * @return
     */
    public static JSONObject getTextFilter(String text) {
        JSONObject jsonObj = new JSONObject();
        try {
            Map<String, String> params = new HashMap<String, String>();
            // 1.设置公共参数
            params.put("secretId", TEXTANDIMAGESECRETID);
            params.put("businessId", TEXTBUSINESSID);
            params.put("version", "v3.1");
            params.put("timestamp", String.valueOf(System.currentTimeMillis()));
            params.put("nonce", String.valueOf(new Random().nextInt()));

            // 2.设置私有参数
            params.put("dataId", UUID.randomUUID().toString());
            params.put("content", text);

            // 3.生成签名信息
            String signature = genSignature(TEXTANDIMAGESECRETKEY, params);
            params.put("signature", signature);

            // 4.发送HTTP请求
            String result = HttpClientUtils.post_str(TEXT_RESULT, params);
            logger.info("易盾智能文本识别接口返回信息:{}", result);

            if (!StringUtils.isEmpty(result)) {
                JSONObject jsonResult = JSONObject.parseObject(result);
                int code = jsonResult.getIntValue("code");
                String msg = jsonResult.getString("msg");
                JSONObject resultJsonObject = jsonResult.getJSONObject("result");
                if (code == 200 && "ok".equals(msg) && !StringUtils.isEmpty(resultJsonObject)) {
                    //检测结果,0:通过,1:嫌疑,2:不通过
                    int action = resultJsonObject.getIntValue("action");
                    String taskId = resultJsonObject.getString("taskId");
                    String labelMsg = "";
                    if (action != 0) {
                        JSONArray labels = resultJsonObject.getJSONArray("labels");
                        labelMsg = "(";
                        if (labels != null && labels.size() > 0) {
                            for (Object obj : labels) {
                                JSONObject jsonObjectone = (JSONObject) obj;
                                Integer label = jsonObjectone.getInteger("label");
                                String name = TextLabels.getName(label);
                                labelMsg = labelMsg + name;

                            }
                        }
                    }

                    if (action == 0) {
                        jsonObj.put("type", "PASS");
                        jsonObj.put("desc", "易盾文本审核通过");
                    }
                    if (action == 1) {
                        jsonObj.put("type", "REJECT");
                        jsonObj.put("desc", "易盾文本审核文本嫌疑" + labelMsg + ")");
                    }
                    if (action == 2) {
                        jsonObj.put("type", "REJECT");
                        jsonObj.put("desc", "易盾文本审核文本违规" + labelMsg + ")");
                    }
                    jsonObj.put("taskId", taskId);
                    logger.info("审核云文本识别处理后结果:{}", jsonObj.toString());
                    return jsonObj;
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        jsonObj.put("type", "REJECT");
        jsonObj.put("desc", "易盾文本识别其它问题需排查");
        logger.info("审核云文本识别处理后结果:{}", jsonObj.toString());
        return jsonObj;
    }

    /**
     * 智能图片审核
     *
     * @param jsonImg //http://test.qnvod.cnlive.com/shen/802/2020/03/01/8a8a878c6dce5cfe017096cd07940c84/000002.jpg
     * @return
     */
    public static JSONObject getImagesFilter(String jsonImg) {
        JSONObject jsonObj = new JSONObject();
        try {
            Map<String, String> params = new HashMap<>(7);
            // 1.设置公共参数
            params.put("secretId", TEXTANDIMAGESECRETID);
            params.put("businessId", IMAGEBUSINESSID);
            params.put("version", "v4");
            params.put("timestamp", String.valueOf(System.currentTimeMillis()));
            params.put("nonce", String.valueOf(new Random().nextInt()));
            params.put("images", jsonImg);

            // 3.生成签名信息
            String signature = genSignature(TEXTANDIMAGESECRETKEY, params);
            params.put("signature", signature);

            // 4.发送HTTP请求,这里使用的是HttpClient工具包,产品可自行选择自己熟悉的工具包发送请求
            String result = HttpClientUtils.post_str(IMAGE_RESULT, params);
            logger.info("易盾智能图片识别接口返回信息:{}", result);

            // 5.解析接口返回值
            if (!StringUtils.isEmpty(result)) {
                JSONObject jsonResult = JSONObject.parseObject(result);
                int code = jsonResult.getIntValue("code");
                String msg = jsonResult.getString("msg");
                int count = 0;
                if (code == 200 && "ok".equals(msg)) {
                    StringBuffer strBuffer = new StringBuffer();
                    strBuffer.append("易盾图片审核");
                    JSONArray antispam = jsonResult.getJSONArray("antispam");
                    if (antispam != null && antispam.size() > 0) {
                        for (int i = 0; i < antispam.size(); i++) {
                            JSONObject jsonObject = antispam.getJSONObject(i);
                            //图片检测状态码,定义为:0:检测成功,610:图片下载失败,620:图片格式错误,630:其它
                            int status = jsonObject.getIntValue("status");
                            //建议动作,2:建议删除,1:建议审核,0:建议通过
                            int action = jsonObject.getIntValue("action");

                            String labelMsg = "";
                            if (action != 0) {
                                JSONArray labels = jsonObject.getJSONArray("labels");
                                if (labels != null && labels.size() > 0) {
                                    for (Object obj : labels) {
                                        JSONObject jsonObjectone = (JSONObject) obj;
                                        int level = jsonObjectone.getIntValue("level");
                                        //分类级别  0-正常 1-不确定 2-确定
                                        if (level != 0) {
                                            Integer label = jsonObjectone.getInteger("label");
                                            String name = ImageLabels.getName(label);
                                            labelMsg = labelMsg + name;
                                        }
                                    }
                                }

                            }

                            if (status == 0 && action == 1) {
                                strBuffer.append("(第" + (i + 1) + "张图片嫌疑" + labelMsg + ")");
                                count++;
                                continue;
                            }
                            if (status == 0 && action == 2) {
                                strBuffer.append("(第" + (i + 1) + "张图片违规" + labelMsg + ")");
                                count++;
                                continue;
                            }
                            if (status != 0) {
                                strBuffer.append("(第" + (i + 1) + "张图片格式问题)");
                                count++;
                                continue;
                            }
                        }
                        if (count > 0) {
                            jsonObj.put("type", "REJECT");
                            jsonObj.put("desc", strBuffer);
                        } else {
                            jsonObj.put("type", "PASS");
                            jsonObj.put("desc", "易盾图片审核通过");
                        }
                        logger.info("审核云图片识别处理后结果:{}", jsonObj.toString());
                        return jsonObj;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        jsonObj.put("type", "REJECT");
        jsonObj.put("desc", "易盾图片识别其它问题需排查");
        logger.info("审核云图片识别处理后结果:{}", jsonObj.toString());
        return jsonObj;
    }

    /**
     * 图文识别检测接口+获取图文检测结果接口(用于测试)
     *
     * @param url
     * @return
     */
    public static JSONObject getURLFilter(String url) {
        Map<String, String> params = new HashMap<String, String>();

        // 1.设置公共参数
        params.put("secretId", SECRETID);
        params.put("version", "v1.0");
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        params.put("nonce", String.valueOf(new Random().nextInt()));

        // 2.设置私有参数
        //数据唯一标识,能够根据该值定位到该条数据(查询作用)
        params.put("dataId", UUID.randomUUID().toString());
        //网页URL, 支持contentType类型: html、txt、doc、docx、ppt、pptx、xls、xlsx、pdf
        params.put("url", url);
        //1:检测文本,2:检测图片,同时检测文本+图片则以逗号分隔,例:1,2。
        params.put("checkFlags", "1,2");
        //不是必传参数
        params.put("callback", UUID.randomUUID().toString());

        // 3.生成签名信息
        String signature = genSignature(SECRETKEY, params);
        params.put("signature", signature);

        // 4.发送HTTP请求
        String s = HttpClientUtils.post_str(URL_SUBMIT, params);
        System.out.println("图文检测提交url结果" + s);


        Map<String, String> params1 = new HashMap<String, String>();
        // 1.设置公共参数
        params1.put("secretId", SECRETID);
        params1.put("version", "v1.0");
        params1.put("timestamp", String.valueOf(System.currentTimeMillis()));
        params1.put("nonce", String.valueOf(new Random().nextInt()));

        // 2.生成签名信息
        String signature1 = genSignature(SECRETKEY, params1);
        params1.put("signature", signature1);

        // 3.发送HTTP请求
        String s1 = HttpClientUtils.post_str(URL_RESULT, params1);
        System.out.println("图文检测获取url结果" + s1);

        // 4.解析接口返回值
        JSONObject resultObject = JSONObject.parseObject(s1);
        return resultObject;
    }

    /**
     * 图文识别检测接口
     *
     * @param url
     * @return
     */
    public static JSONObject submitYiDunUrl(String url) {
        try {
            logger.info("审核云向易盾网站检测接口提交的url.....................");
            Map<String, String> params = new HashMap<String, String>();

            // 1.设置公共参数
            params.put("secretId", SECRETID);
            params.put("version", "v1.0");
            params.put("timestamp", String.valueOf(System.currentTimeMillis()));
            params.put("nonce", String.valueOf(new Random().nextInt()));

            // 2.设置私有参数
            //数据唯一标识,能够根据该值定位到该条数据(查询作用)
            params.put("dataId", UUID.randomUUID().toString());
            //网页URL, 支持contentType类型: html、txt、doc、docx、ppt、pptx、xls、xlsx、pdf
            params.put("url", url);
            //1:检测文本,2:检测图片,同时检测文本+图片则以逗号分隔,例:1,2。
            params.put("checkFlags", "1,2");
            //不是必传参数
            params.put("callback", UUID.randomUUID().toString());

            // 3.生成签名信息
            String signature = YiDunAntiFraudUtil.genSignature(SECRETKEY, params);
            params.put("signature", signature);

            // 4.发送HTTP请求
            String s = HttpClientUtils.post_str(URL_SUBMIT, params);
            logger.info("审核云向易盾提交网站检测地址返回的结果:{}", s);
            JSONObject jsonObject = JSONObject.parseObject(s);
            int code = jsonObject.getIntValue("code");
            String msg = jsonObject.getString("msg");
            if (code == 200 && "ok".equals(msg)) {
                return jsonObject;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 生成签名信息
     *
     * @param secretKey 产品私钥
     * @param params    接口请求参数名和参数值map,不包括signature参数名
     * @return
     */
    public static String genSignature(String secretKey, Map<String, String> params) {
        // 1. 参数名按照ASCII码表升序排序
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);

        // 2. 按照排序拼接参数名与参数值
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            sb.append(key).append(params.get(key));
        }
        // 3. 将secretKey拼接到最后
        sb.append(secretKey);

        // 4. MD5是128位长度的摘要算法,转换为十六进制之后长度为32字符
        try {
            String s = DigestUtils.md5Hex(sb.toString().getBytes("UTF-8"));
            return s;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 做签名验证
     *
     * @param secretId
     * @param businessId
     * @param signature
     * @param callbackData
     * @return
     */
    public static boolean verifySignature(String secretId, String businessId, String signature, String callbackData) {
        if (org.apache.commons.lang3.StringUtils.isEmpty(secretId) || org.apache.commons.lang3.StringUtils.isEmpty(signature)) {
            // 签名参数为空,直接返回失败
            return false;
        }
        Map<String, String> params = new HashMap<>(3);
        params.put("secretId", secretId);
        params.put("businessId", businessId);
        params.put("callbackData", callbackData);

        // SECRETKEY:产品私有密钥 SECRETID:产品密钥ID BUSINESSID:业务ID,开通服务时,易盾会提供相关密钥信息
        String serverSignature = genSignature(TEXTANDIMAGESECRETKEY, params);
        return signature.equals(serverSignature) && TEXTANDIMAGESECRETID.equals(secretId) && AUDIOONDEMANDBUSINESSID.equals(businessId);
    }


}