Browse Source

协鼎单点登录

lihui007 3 years ago
parent
commit
aaace5ba25

+ 50 - 0
common/src/main/java/com/huaxu/util/MD5Util.java

@@ -0,0 +1,50 @@
+package com.huaxu.util;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MD5Util {
+
+    public static String digest(String inbuf) {
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            md.update(inbuf.getBytes());
+            byte b[] = md.digest();
+            int i;
+            StringBuffer buf = new StringBuffer("");
+            for (int offset = 0; offset < b.length; offset++) {
+                i = b[offset];
+                if (i < 0) {
+                    i += 256;
+                }
+                if (i < 16) {
+                    buf.append("0");
+                }
+                buf.append(Integer.toHexString(i));
+            }
+            return buf.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
+        "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
+        "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
+        "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
+        "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+        "W", "X", "Y", "Z"};
+
+    //根据加密后的MD5生成8位字符串
+    public static String generateShort(String str) {
+        StringBuffer shortBuffer = new StringBuffer();
+        String digStr = digest(str);
+        for (int i = 0; i < 8; i++) {
+            String newStr = digStr.substring(i * 4, i * 4 + 4);
+            int x = Integer.parseInt(newStr, 16);
+            shortBuffer.append(chars[x % 0x3E]);
+        }
+        return shortBuffer.toString();
+    }
+}

+ 31 - 0
user_auth/src/main/java/com/huaxu/config/SsoConfig.java

@@ -0,0 +1,31 @@
+package com.huaxu.config;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+/**
+ * @ClassName SsoConfig
+ * @Description: 单点登录相关配置
+ * @Author lihui
+ * @Date 2021/4/9
+ * @Version V1.0
+ **/
+@Data
+@Configuration
+@Component
+public class SsoConfig {
+
+    // 根据账户获取密码
+    @Value("${sso.xieding.get.pwd.url}")
+    private String pwdUrl;
+
+    // 绑定单点登陆用户
+    @Value("${sso.xieding.bind.single.url}")
+    private String bindSingleUrl;
+
+    // 获取token
+    @Value("${sso.xieding.get.token.url}")
+    private String tokenUrl;
+}

+ 43 - 0
user_auth/src/main/java/com/huaxu/controller/ThirdPartyLoginController.java

@@ -0,0 +1,43 @@
+package com.huaxu.controller;
+
+
+import com.huaxu.dto.thirdparty.LoginQueryDto;
+import com.huaxu.exception.ServiceException;
+import com.huaxu.model.AjaxMessage;
+import com.huaxu.model.ResultStatus;
+import com.huaxu.service.ThirdPartyLoginService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * @ClassName ThirdPartyLoginController
+ * @Description: 第三方登录登录业务处理
+ * @Author lihui
+ * @Date 2021/4/7
+ * @Version V1.0
+ **/
+@RestController
+@RequestMapping("/third/party/login")
+@Api(tags = "第三方登录")
+public class ThirdPartyLoginController {
+
+    @Autowired
+    private ThirdPartyLoginService xiedingLoginService;
+
+    @RequestMapping(value = "/getXieDingToken", method = RequestMethod.POST)
+    @ApiOperation(value = "获取协鼎登录的token")
+    public AjaxMessage<String> getXieDingToken(@ApiParam(value = "获取token信息", required = true) @RequestBody LoginQueryDto queryDto) {
+       try {
+           return new AjaxMessage<>(ResultStatus.OK, xiedingLoginService.getToken(queryDto));
+        } catch (ServiceException e) {
+           return new AjaxMessage<>(e.getStatus(), e.getMessage(), null);
+        }
+    }
+}

+ 2 - 0
user_auth/src/main/java/com/huaxu/dao/UserMapper.java

@@ -112,4 +112,6 @@ public interface UserMapper {
     String getAppSecret(String appId);
 
     void updateUniqueUserID(@Param("id")Integer id, @Param("uid") String uid);
+
+    User findThirdPartytLoginInfo(String tenantId, String phone);
 }

+ 19 - 0
user_auth/src/main/java/com/huaxu/dto/thirdparty/LoginQueryDto.java

@@ -0,0 +1,19 @@
+package com.huaxu.dto.thirdparty;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+/**
+ * @ClassName LoginQueryDto
+ * @Description: 第三方登录查询实体
+ * @Author lihui
+ * @Date 2021/4/7
+ * @Version V1.0
+ **/
+@Data
+public class LoginQueryDto {
+
+    @ApiModelProperty(value="菜单ID")
+    private int menuId;
+}

+ 24 - 0
user_auth/src/main/java/com/huaxu/dto/thirdparty/XieDingResultDto.java

@@ -0,0 +1,24 @@
+package com.huaxu.dto.thirdparty;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+@Data
+public class XieDingResultDto {
+
+    @ApiModelProperty(value="状态")
+    private boolean status;
+
+    @ApiModelProperty(value="消息")
+    private String  msg;
+
+    @ApiModelProperty(value="密码")
+    private String password;
+
+    @ApiModelProperty(value="singleKey")
+    private String singleKey;
+
+    @ApiModelProperty(value="token")
+    private String token;
+}

+ 12 - 0
user_auth/src/main/java/com/huaxu/entity/User.java

@@ -104,4 +104,16 @@ public class User implements Serializable {
     private String iotPhoneNumber;
     private String customerId;
 
+    @ApiModelProperty(value = "登录第三方账号")
+    private String loginAccount;
+
+    @ApiModelProperty(value = "登录第三方密钥")
+    private String loginSecretKey;
+
+    @ApiModelProperty(value = "登录第三方厂家编码")
+    private String loginCode;
+
+    @ApiModelProperty(value = "登录第三方机构编码")
+    private String loginOrgCode;
+
 }

+ 15 - 0
user_auth/src/main/java/com/huaxu/service/ThirdPartyLoginService.java

@@ -0,0 +1,15 @@
+package com.huaxu.service;
+
+import com.huaxu.dto.thirdparty.LoginQueryDto;
+
+public interface ThirdPartyLoginService {
+
+    /**
+    * @Author lihui
+    * @Description 获取登录需要的token
+    * @Date 16:39 2021/4/7
+    * @Param []
+    * @return java.lang.String
+    **/
+    String getToken(LoginQueryDto dto);
+}

+ 79 - 0
user_auth/src/main/java/com/huaxu/service/impl/thirdparty/XiedingLoginServiceImpl.java

@@ -0,0 +1,79 @@
+package com.huaxu.service.impl.thirdparty;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.client.config.utils.MD5;
+import com.alibaba.nacos.common.util.Md5Utils;
+import com.huaxu.config.SsoConfig;
+import com.huaxu.dao.UserMapper;
+import com.huaxu.dto.thirdparty.LoginQueryDto;
+import com.huaxu.dto.thirdparty.XieDingResultDto;
+import com.huaxu.entity.User;
+import com.huaxu.exception.ServiceException;
+import com.huaxu.model.LoginUser;
+import com.huaxu.model.ResultStatus;
+import com.huaxu.service.ThirdPartyLoginService;
+import com.huaxu.util.HttpClientPoolUtil;
+import com.huaxu.util.MD5Util;
+import com.huaxu.util.UserUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.Charset;
+
+/**
+ * @ClassName XiedingLoginServiceImpl
+ * @Description: 协鼎单点登录业务处理
+ * @Author lihui
+ * @Date 2021/4/7
+ * @Version V1.0
+ **/
+@Service("xiedingLoginService")
+public class XiedingLoginServiceImpl implements ThirdPartyLoginService {
+
+
+    @Autowired
+    private SsoConfig ssoConfig;
+
+    @Autowired
+    private UserMapper userMapper;
+
+    @Override
+    public String getToken(LoginQueryDto queryDto) {
+        String httpIpPortUrl  = "http://www.xdwater365.com/yhfw/security/security";
+        LoginUser currentUser = UserUtil.getCurrentUser();
+        User user = userMapper.findThirdPartytLoginInfo(currentUser.getTenantId(), currentUser.getPhoneNumber());
+        if (user == null || StringUtils.isEmpty(user.getLoginAccount())){
+            throw new ServiceException(ResultStatus.ERROR.getStatus(), "未设置登录账号");
+        }
+        // 登录账号、登录密钥、厂家编码、机构编码
+        String account   = user.getLoginAccount();
+        String secretKey = user.getLoginSecretKey();
+        String code      = user.getLoginCode();
+        String orgCode   = user.getLoginOrgCode();
+        Charset charset  = Charset.forName("utf-8");
+        // 1.根据账户获取密码
+        String result = HttpClientPoolUtil.sendGet(String.format(ssoConfig.getPwdUrl(), httpIpPortUrl, account, orgCode), charset);
+        XieDingResultDto resultDto = JSONObject.parseObject(result, XieDingResultDto.class);
+        if (StringUtils.isEmpty(resultDto.getPassword())) {
+            throw new ServiceException(ResultStatus.ERROR.getStatus(), resultDto.getMsg());
+        }
+        // 2.绑定单点登陆用户
+        result    = HttpClientPoolUtil.sendGet(String.format(ssoConfig.getBindSingleUrl(), httpIpPortUrl, account, resultDto.getPassword(), orgCode), charset);
+        resultDto = JSONObject.parseObject(result, XieDingResultDto.class);
+        if (!resultDto.isStatus()) {
+            throw new ServiceException(ResultStatus.ERROR.getStatus(), resultDto.getMsg());
+        }
+        // 3.获取token
+        String singleKey = resultDto.getSingleKey();
+        Long timestamp   = System.currentTimeMillis();
+        String sign      = MD5Util.digest(resultDto.getSingleKey() + timestamp + secretKey);
+        result    = HttpClientPoolUtil.sendGet(String.format(ssoConfig.getTokenUrl(), httpIpPortUrl, singleKey, timestamp, sign, code), charset);
+        resultDto = JSONObject.parseObject(result, XieDingResultDto.class);
+        if (!resultDto.isStatus()) {
+            throw new ServiceException(ResultStatus.ERROR.getStatus(), resultDto.getMsg());
+        }
+        return resultDto.getToken();
+    }
+
+}

+ 320 - 0
user_auth/src/main/java/com/huaxu/util/HttpClientPoolUtil.java

@@ -0,0 +1,320 @@
+package com.huaxu.util;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.SocketTimeoutException;
+import java.nio.charset.Charset;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Slf4j
+public class HttpClientPoolUtil {
+
+    private static HttpClient httpClient = null;
+
+    public static synchronized HttpClient getHttpClient() {
+        if (httpClient == null) {
+            httpClient = createHttpClient(100, 20, 10000, 3000, 3000);
+        }
+        return httpClient;
+    }
+
+    /**
+     * 实例化HttpClient
+     */
+    public static HttpClient createHttpClient(int maxTotal, int maxPerRoute, int socketTimeout,
+        int connectTimeout,
+        int connectionRequestTimeout) {
+        RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout)
+            .setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectionRequestTimeout)
+            .build();
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+        cm.setMaxTotal(maxTotal);
+        cm.setDefaultMaxPerRoute(maxPerRoute);
+        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
+            .setDefaultRequestConfig(defaultRequestConfig).build();
+        return httpClient;
+    }
+
+
+    /**
+     * 发送post请求
+     *
+     * @param url 请求地址
+     * @param params 请求参数
+     * @param encoding 编码
+     */
+    public static String sendPost(String url, Map<String, String> params, Charset encoding) {
+        String resp = "";
+        HttpPost httpPost = new HttpPost(url);
+        if (params != null && params.size() > 0) {
+            List<NameValuePair> formParams = new ArrayList<NameValuePair>();
+            Iterator<Entry<String, String>> itr = params.entrySet().iterator();
+            while (itr.hasNext()) {
+                Entry<String, String> entry = itr.next();
+                formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+            }
+            UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(formParams, encoding);
+            httpPost.setEntity(postEntity);
+        }
+        CloseableHttpResponse response = null;
+        try {
+            response = (CloseableHttpResponse) getHttpClient().execute(httpPost);
+            resp = EntityUtils.toString(response.getEntity(), encoding);
+        } catch (Exception e) {
+            log.error("httpClient pool error === [" + url + "]> ", e);
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return resp;
+    }
+
+    /**
+     * 发送post请求
+     *
+     * @param url 请求地址
+     * @param params 请求参数
+     * @param encoding 编码
+     */
+    public static String sendPost(String url, Map<String, String> params,
+        Map<String, String> headerMap, Charset encoding) {
+        String resp = "";
+        HttpPost httpPost = new HttpPost(url);
+
+        // 添加请求参数
+        if (isNotEmpty(params)) {
+            List<NameValuePair> formParams = new ArrayList<NameValuePair>();
+            Iterator<Entry<String, String>> itr = params.entrySet().iterator();
+            while (itr.hasNext()) {
+                Entry<String, String> entry = itr.next();
+                formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
+            }
+            UrlEncodedFormEntity postEntity = new UrlEncodedFormEntity(formParams, encoding);
+            httpPost.setEntity(postEntity);
+        }
+
+        // 添加头部参数
+        if (isNotEmpty(headerMap)) {
+            Iterator<Entry<String, String>> iter = headerMap.entrySet().iterator();
+            while (iter.hasNext()) {
+                Entry<String, String> element = (Entry<String, String>) iter
+                    .next();
+                httpPost.addHeader(element.getKey(), element.getValue());
+            }
+        }
+
+        CloseableHttpResponse response = null;
+        try {
+            response = (CloseableHttpResponse) getHttpClient().execute(httpPost);
+            resp = EntityUtils.toString(response.getEntity(), encoding);
+        } catch (SocketTimeoutException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            log.error("httpClient pool error === [" + url + "]> ", e);
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return resp;
+    }
+
+    /**
+     * @Description 发送post json参数
+     */
+    public static String sendPost(String url, String json, Charset encoding) {
+        String resp = "";
+        CloseableHttpResponse response = null;
+        HttpPost httpPost = new HttpPost(url);
+        if (StringUtils.isNotEmpty(json)) {
+            try {
+                StringEntity se = new StringEntity(json);
+
+                se.setContentType("text/json");
+
+                se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
+                httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
+                httpPost.addHeader("Connection", "close");
+                httpPost.setEntity(se);
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            response = (CloseableHttpResponse) getHttpClient().execute(httpPost);
+            resp = EntityUtils.toString(response.getEntity(), encoding);
+        } catch (Exception e) {
+            log.error("httpClient pool error === [" + url + "=" + json + "]> ", e);
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return resp;
+    }
+
+    /**
+     * @Description 发送post json参数
+     */
+    public static String sendPost(String url, String json, Charset encoding, String contentType) {
+        String resp = "";
+        CloseableHttpResponse response = null;
+        HttpPost httpPost = new HttpPost(url);
+        if (StringUtils.isNotEmpty(json)) {
+            StringEntity se = new StringEntity(json, "utf-8");
+            se.setContentType("text/json");
+            if (StringUtils.isBlank(contentType)) {//默认 请求
+                httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json;charset=utf-8");
+            } else {
+                httpPost.addHeader(HTTP.CONTENT_TYPE, contentType);
+            }
+            httpPost.addHeader("Connection", "close");
+            httpPost.setEntity(se);
+        }
+        try {
+            response = (CloseableHttpResponse) getHttpClient().execute(httpPost);
+            resp = EntityUtils.toString(response.getEntity(), encoding);
+        } catch (Exception e) {
+            log.error("httpClient pool error === [" + url + "=" + json + "]> ", e);
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return resp;
+    }
+
+
+    /**
+     * @Description 发送post json参数
+     */
+    public static String sendGet(String url, Charset encoding) {
+        String resp = "";
+        CloseableHttpResponse response = null;
+        HttpGet httpPost = new HttpGet(url);
+        try {
+            httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
+            httpPost.addHeader("Connection", "close");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            response = (CloseableHttpResponse) getHttpClient().execute(httpPost);
+            resp = EntityUtils.toString(response.getEntity(), encoding);
+        } catch (Exception e) {
+            log.error("httpClient pool error === [" + url + "]> ", e);
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return resp;
+    }
+
+
+    public static String sendGetReferer(String url, Charset encoding, String referer) {
+
+        String resp = "";
+
+        CloseableHttpResponse response = null;
+
+        HttpGet httpPost = new HttpGet(url);
+
+        try {
+            httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
+            httpPost.addHeader("Connection", "close");
+            httpPost.setHeader("referer", referer);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        try {
+            response = (CloseableHttpResponse) getHttpClient().execute(httpPost);
+            resp = EntityUtils.toString(response.getEntity(), encoding);
+        } catch (Exception e) {
+            log.error("httpClient pool error === [" + url + "]> ", e);
+        } finally {
+            if (response != null) {
+                try {
+                    response.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return resp;
+    }
+
+
+    private static boolean isNotEmpty(Map<String, String> headerMap) {
+        if (headerMap == null || headerMap.size() == 0) {
+            return false;
+        }
+        return true;
+    }
+
+    public static Long timeToSecond() {
+        String dateStr = "1970-1-1 08:00:00";
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        long aftertime = 0;
+        try {
+            Date miDate = sdf.parse(dateStr);
+            long d1time = System.currentTimeMillis() / 1000;
+            long t1time = miDate.getTime() / 1000;
+            aftertime = d1time - t1time;
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return aftertime;
+
+    }
+
+}

+ 4 - 1
user_auth/src/main/resources/application-dev.properties

@@ -79,5 +79,8 @@ dispath.routing.key=dipathKey
 iot.url=http://localhost:8090
 
 
-
+#µ¥µãµÇ¼µÚÈý·½ÇëÇóurl
+sso.xieding.get.pwd.url=%s!getSingleLandUser.action?account=%s&orgCode=%s
+sso.xieding.bind.single.url=%s!bindingSingleLandUser.action?account=%s&password=%s&orgCode=%s
+sso.xieding.get.token.url=%s!createSingleLandToken.action?singleKey=%s&timestamp=%s&signatrue=%s&code=%s
 

+ 4 - 0
user_auth/src/main/resources/mapper/UserMapper.xml

@@ -341,4 +341,8 @@
     <update id="updateUniqueUserID">
         update uims_user set uniq_id=#{uid} where id=#{id}
     </update>
+
+    <select id="findThirdPartytLoginInfo" resultType="com.huaxu.entity.User">
+        select login_account loginAccount,login_secret_key loginSecretKey,login_code loginCode,login_org_code loginOrgCode from uims_user  where  TENANT_ID =#{tenantId} and PHONE = #{phone}
+    </select>
 </mapper>