作者 朱兆平

add: 新增对接统一认证资源同步接口

@@ -11,6 +11,7 @@ import com.tianbo.warehouse.controller.response.ResultJson; @@ -11,6 +11,7 @@ import com.tianbo.warehouse.controller.response.ResultJson;
11 import com.tianbo.warehouse.dao.UserRoleMapper; 11 import com.tianbo.warehouse.dao.UserRoleMapper;
12 import com.tianbo.warehouse.model.*; 12 import com.tianbo.warehouse.model.*;
13 import com.tianbo.warehouse.security.filter.JwtTokenUtil; 13 import com.tianbo.warehouse.security.filter.JwtTokenUtil;
  14 +import com.tianbo.warehouse.security.login.TokenUtils;
14 import com.tianbo.warehouse.service.PermissionService; 15 import com.tianbo.warehouse.service.PermissionService;
15 import com.tianbo.warehouse.service.RoleService; 16 import com.tianbo.warehouse.service.RoleService;
16 17
@@ -266,8 +267,77 @@ public class AnonymousController { @@ -266,8 +267,77 @@ public class AnonymousController {
266 */ 267 */
267 @PostMapping(value = "/userSynchronization") 268 @PostMapping(value = "/userSynchronization")
268 @ResponseBody 269 @ResponseBody
269 - public ResultMessage userSynchronization(@RequestBody Map<String, Object> map){ 270 + public ResultMessage userSynchronization(@RequestBody Map<String, Object> map, @RequestHeader Map<String, String> headers,HttpServletRequest request){
270 log.info("[SSO-资源同步]-参数打印:\n{}",map.toString()); 271 log.info("[SSO-资源同步]-参数打印:\n{}",map.toString());
  272 + headers.forEach((key,value)->{
  273 + log.info("[SSO-USER-SYNCHRONIZATION-HEADER-INFO]-key:{},value:{}",key,value);
  274 + });
  275 +
  276 + //IP白名单
  277 + List<String> ipWhiteList = Arrays.asList(
  278 + "10.5.14.108",
  279 + "10.5.14.109",
  280 + "10.5.14.110",
  281 + "127.0.0.1"
  282 + );
  283 +
  284 + String requestRemoteAddr = request.getHeader("X-Forwarded-For");
  285 +
  286 + if (StringUtils.isEmpty(requestRemoteAddr)){
  287 + requestRemoteAddr = request.getRemoteAddr();
  288 + }else {
  289 + requestRemoteAddr = requestRemoteAddr.split(",")[0];
  290 + }
  291 +
  292 + if (ipWhiteList.contains(requestRemoteAddr)){
  293 + log.info("[SSO-USER-SYNCHRONIZATION-IPWhiteList]-ipWhiteList:[{}]",requestRemoteAddr);
  294 + }else {
  295 + log.info("[SSO-USER-SYNCHRONIZATION-IPWhiteList]-ip:[{}]白名单验证失败,访问IP不在白名单内",requestRemoteAddr);
  296 + return new ResultMessage(400,"访问IP不在白名单内,验证失败.ip:"+requestRemoteAddr);
  297 + }
  298 +
  299 + // 用headers Map 取值 key 键值时 key会全部转为小写 在springboot 中
  300 + if (headers.containsKey("once") && headers.containsKey("ts") && headers.containsKey("appkey") && headers.containsKey("signmethod") && headers.containsKey("signdata")){
  301 + String appAuthKey = "4768711539138560" ;
  302 + if (appAuthKey.equals(headers.get("appkey"))){
  303 + String bodyData = JSON.toJSONString(map);
  304 + String appPwd = "ce10ec6cc310966de5264994817a0f7c1b2b9e3b";
  305 + log.info("[SSO-INFO]-apppwd:{}",appPwd);
  306 + StringBuilder sb = new StringBuilder();
  307 + //签名验证格式拼接
  308 +
  309 + sb.append("appKey=").append(headers.get("appkey"))
  310 + .append("&ts=").append(headers.get("ts"))
  311 + .append("&once=").append(headers.get("once"))
  312 + .append("&signMethod=").append(headers.get("signmethod"))
  313 + .append("&bodyData=").append(bodyData);
  314 + String signAuthURI = sb.toString();
  315 + // 签名生成
  316 + try{
  317 + String signData = TokenUtils.getSignature(appPwd, signAuthURI);
  318 + // 签名验证
  319 + if (signData.equals(headers.get("signdata"))){
  320 + log.info("[SSO-USER-SYNCHRONIZATION-HEADER-SUCCESS]-头部签名验证成功");
  321 + }else {
  322 + log.error("[SSO-USER-SYNCHRONIZATION-HEADER-AUTHFAIL]-头部签名验证失败");
  323 +// return new ResultMessage(400,"app签名验证失败");
  324 + }
  325 + }catch (Exception e){
  326 + log.error("[SSO-USER-SYNCHRONIZATION-HEADER-AUTH-ERR]-",e);
  327 +// return new ResultMessage(400,"app签名验证出错"+e.getMessage());
  328 + }
  329 +
  330 + }else {
  331 + log.error("[SSO-USER-SYNCHRONIZATION-HEADER-FAILD],key:{},不为验证key:4768711539138560",headers.get("appKey"));
  332 +// return new ResultMessage(400,"appKey验证失败");
  333 + }
  334 + }else {
  335 + log.error("[SSO-USER-SYNCHRONIZATION-HEADER-FAILD]-缺少必要头部验证信息");
  336 +// return new ResultMessage(400,"缺少必要头部验证信息,app验证失败");
  337 + }
  338 +
  339 +
  340 +
271 //获取action的值,判断是push数据还是删除数据 341 //获取action的值,判断是push数据还是删除数据
272 String action = map.get("action").toString(); 342 String action = map.get("action").toString();
273 if ("user".equals(map.get("resType").toString())){ 343 if ("user".equals(map.get("resType").toString())){
@@ -14,13 +14,15 @@ public class SSOUserData { @@ -14,13 +14,15 @@ public class SSOUserData {
14 14
15 private String USER_NO; 15 private String USER_NO;
16 16
  17 + private Integer USER_TYPE;
  18 +
17 private String MOBILE; 19 private String MOBILE;
18 20
19 private String IDCARD_NO; 21 private String IDCARD_NO;
20 22
21 private String COUNTRY; 23 private String COUNTRY;
22 24
23 - private String SEX; 25 + private Integer SEX;
24 26
25 private String NATIONALITY; 27 private String NATIONALITY;
26 28
@@ -34,9 +36,11 @@ public class SSOUserData { @@ -34,9 +36,11 @@ public class SSOUserData {
34 36
35 private String JOB_TITLE; 37 private String JOB_TITLE;
36 38
37 - private String JOB_TYPE; 39 + private Integer JOB_TYPE;
  40 +
  41 + private Integer JOB_STATUS;
38 42
39 - private String JOB_STATUS; 43 + private Integer USER_JOB_STATUS;
40 44
41 private String JOB_POSITION; 45 private String JOB_POSITION;
42 46
@@ -52,7 +56,7 @@ public class SSOUserData { @@ -52,7 +56,7 @@ public class SSOUserData {
52 56
53 private String LOGIN_NAME; 57 private String LOGIN_NAME;
54 58
55 - private String SHOW_ORDER; 59 + private Integer SHOW_ORDER;
56 60
57 private String REMARK; 61 private String REMARK;
58 62
@@ -64,5 +68,5 @@ public class SSOUserData { @@ -64,5 +68,5 @@ public class SSOUserData {
64 68
65 private String PWD_ENCRYPT; 69 private String PWD_ENCRYPT;
66 70
67 - private String UPDATE_TIME; 71 + private Long UPDATE_TIME;
68 } 72 }
  1 +package com.tianbo.warehouse.security.login;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.apache.commons.lang3.StringUtils;
  5 +import org.apache.commons.lang3.ArrayUtils;
  6 +import org.bouncycastle.crypto.digests.SM3Digest;
  7 +
  8 +import java.io.UnsupportedEncodingException;
  9 +import java.net.URLDecoder;
  10 +import java.security.MessageDigest;
  11 +import java.security.NoSuchAlgorithmException;
  12 +import java.util.Arrays;
  13 +
  14 +@Slf4j
  15 +public class TokenUtils {
  16 +
  17 + private static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e",
  18 + "f" };
  19 +
  20 + public static String getSignature(String pwd, String paramUrl) {
  21 +
  22 +
  23 + if (StringUtils.isNotBlank(paramUrl)) {
  24 + try {
  25 + paramUrl = URLDecoder.decode(paramUrl, "UTF-8");
  26 + } catch (UnsupportedEncodingException e) {
  27 + log.error("SM3生成signData失败:", e);
  28 + throw new RuntimeException("生成signData失败:", e);
  29 + }
  30 + }
  31 +
  32 + String[] paraArray = new String[] {};
  33 + if (StringUtils.isNotBlank(paramUrl)) {
  34 + String[] queryArray = paramUrl.split("&");
  35 + paraArray = (String[]) ArrayUtils.addAll(queryArray, paraArray);
  36 + }
  37 +
  38 + Arrays.sort(paraArray);
  39 +
  40 + StringBuffer buffer = new StringBuffer();
  41 + buffer.append(pwd);
  42 + buffer.append(":");
  43 +
  44 + for (int i = 0; i < paraArray.length; i++) {
  45 + buffer.append(paraArray[i]);
  46 + buffer.append("&");
  47 + }
  48 + buffer.deleteCharAt(buffer.length() - 1);
  49 + buffer.append(":");
  50 + buffer.append(pwd);
  51 +
  52 + MessageDigest md = null;
  53 + SM3Digest digest = new SM3Digest();
  54 + String sm3Encode1 = "";
  55 + try {
  56 + md = MessageDigest.getInstance("SHA-256");
  57 + md.update(buffer.toString().getBytes("UTF-8"));
  58 +
  59 + //SM3
  60 + digest.update(buffer.toString().getBytes("UTF-8"),0, buffer.length());
  61 + byte[] hashSM3 = new byte[digest.getDigestSize()];
  62 + digest.doFinal(hashSM3, 0);
  63 + sm3Encode1 = byteArrayToHexString(hashSM3);
  64 + log.info("[sm3Encode1] = {}" , sm3Encode1);
  65 +
  66 + } catch (NoSuchAlgorithmException e) {
  67 + log.error("生成signData失败:", e);
  68 + throw new RuntimeException("生成signData失败.", e);
  69 + } catch (UnsupportedEncodingException e) {
  70 + log.error("生成signData失败:", e);
  71 + throw new RuntimeException("生成signData失败.", e);
  72 + }
  73 + String encode = byteArrayToHexString(md.digest());
  74 + log.info("[SHA256-ENCODE]={}" , encode);
  75 + String sm3Encode = SM3EncryptUtil.passwordSm3(buffer.toString());
  76 + log.info("[sm3PasswordEncode] = {} " , sm3Encode);
  77 + return sm3Encode;
  78 + }
  79 +
  80 + private static String byteArrayToHexString(byte[] byteArray) {
  81 + StringBuffer sb = new StringBuffer();
  82 + for (byte byt : byteArray) {
  83 + sb.append(byteToHexString(byt));
  84 + }
  85 + return sb.toString();
  86 + }
  87 +
  88 + private static String byteToHexString(byte byt) {
  89 + int n = byt;
  90 + if (n < 0)
  91 + n = 256 + n;
  92 + return hexDigits[n / 16] + hexDigits[n % 16];
  93 + }
  94 +}