ソースを参照

Merge branch 'master' of http://62.234.61.92:3000/wjm/mec-cloud_IntelligentManufacturing_CRM

lph 1 年間 前
コミット
d54b4cc6f3

+ 6 - 0
zkqy-admin/pom.xml

@@ -68,6 +68,12 @@
             <artifactId>zkqy-generator</artifactId>
         </dependency>
 
+        <!-- https://mvnrepository.com/artifact/org.jodd/jodd-http -->
+        <dependency>
+            <groupId>org.jodd</groupId>
+            <artifactId>jodd-http</artifactId>
+            <version>6.2.1</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 58 - 19
zkqy-admin/src/main/java/com/zkqy/web/controller/system/SysLoginController.java

@@ -1,10 +1,13 @@
 package com.zkqy.web.controller.system;
 
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 import java.util.List;
 import java.util.Set;
 
 import com.zkqy.common.core.domain.entity.DataSource;
 import com.zkqy.common.core.domain.entity.SysTenant;
+import com.zkqy.common.utils.StringUtils;
 import com.zkqy.framework.web.service.TokenService;
 import com.zkqy.system.service.IDataSourceService;
 import com.zkqy.system.service.ILoginPageConfigurationService;
@@ -13,10 +16,7 @@ import com.zkqy.system.service.impl.SysTenantServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.validation.BindingResult;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import com.zkqy.common.constant.Constants;
 import com.zkqy.common.core.domain.AjaxResult;
 import com.zkqy.common.core.domain.entity.SysMenu;
@@ -112,21 +112,6 @@ public class SysLoginController {
         return ajax;
     }
 
-    /**
-     * 验证租户i是否存在有效
-     *
-     * @param tenantCode 租户编号
-     * @return
-     */
-    @GetMapping("/isTenantExist")
-    public AjaxResult isTenantExist(String tenantCode) {
-        SysTenant sysTenantInfo = iSysTenantService.selectSysTenantByTenantCode(tenantCode);
-        if (sysTenantInfo != null) {
-            sysTenantInfo.setLoginPageConfiguration(loginPageConfigurationService.selectLoginPageConfigurationByLoginPageNumber(tenantCode, "tool"));
-            return AjaxResult.success(sysTenantInfo);
-        }
-        return AjaxResult.error("租户不存在");
-    }
 
     /**
      * 登录方法
@@ -155,6 +140,60 @@ public class SysLoginController {
     }
 
 
+    /**
+     * 登录方法
+     *
+     * @param tenantCode 登录信息
+     * @return 结果
+     */
+    @GetMapping("/Oauth2Login/{loginInfo}")
+    public AjaxResult Oauth2Login(@PathVariable String loginInfo) {
+        if (StringUtils.isEmpty(loginInfo)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        // 恢复(解码)数据
+        byte[] decodedBytes = Base64.getDecoder().decode(loginInfo);
+        String decodedCredentials = new String(decodedBytes, StandardCharsets.UTF_8);
+        String[] code = decodedCredentials.split("\\^\\_\\^");
+        if (code.length != 3) {
+            return AjaxResult.error("用户不存在!");
+        }
+        LoginBody loginBody = new LoginBody();
+        loginBody.setTenantID(code[0]);
+        loginBody.setUsername(code[1]);
+        AjaxResult ajax = AjaxResult.success();
+        // 生成令牌
+        String token = loginService.loginOauth(code[0], code[1]);
+        if (tokenService.getLoginUserIsAdminByToken(token)) {
+            return AjaxResult.error("用户不存在!");
+        }
+        // 校验租户是否过期
+        String checkTenantExpirationTimeMsg = loginService.checkTenantExpirationTimeOauth(loginBody);
+
+        if (!checkTenantExpirationTimeMsg.isEmpty()) {
+            return AjaxResult.error(checkTenantExpirationTimeMsg);
+        }
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+
+    /**
+     * 验证租户i是否存在有效
+     *
+     * @param tenantCode 租户编号
+     * @return
+     */
+    @GetMapping("/isTenantExist")
+    public AjaxResult isTenantExist(String tenantCode) {
+        SysTenant sysTenantInfo = iSysTenantService.selectSysTenantByTenantCode(tenantCode);
+        if (sysTenantInfo != null) {
+            sysTenantInfo.setLoginPageConfiguration(loginPageConfigurationService.selectLoginPageConfigurationByLoginPageNumber(tenantCode, "tool"));
+            return AjaxResult.success(sysTenantInfo);
+        }
+        return AjaxResult.error("租户不存在");
+    }
+
     /**
      * 获取用户信息
      *

+ 101 - 0
zkqy-admin/src/main/java/com/zkqy/web/controller/system/ThirdPartLoginController.java

@@ -0,0 +1,101 @@
+package com.zkqy.web.controller.system;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.utils.http.HttpUtilsOauth2;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 第三方登录验证
+ *
+ * @author hzh
+ */
+@Controller
+public class ThirdPartLoginController {
+
+    @Value("${OpenAuthorization2.GLY.URL}")
+    private String URL;
+
+    @Value("${OpenAuthorization2.GLY.BASIC}")
+    private String BASIC;
+
+    @Value("${OpenAuthorization2.GLY.REDIRECT_URL}")
+    private String REDIRECT_URL;
+
+    @Value("${OpenAuthorization2.GLY.CALLBACK}")
+    private String CALLBACK;
+
+    @GetMapping("oauth/callback")
+    public String callback(@RequestParam("code") String code, HttpSession session, HttpServletRequest request) {
+        try {
+            // 封装获取token请求参数
+            Map<String, String> map = new HashMap<>();
+            map.put("grant_type", "authorization_code");
+            map.put("redirect_uri", CALLBACK);
+            map.put("code", code);
+            // 获取token请求头
+            Map<String, String> headers = new HashMap<>();
+            // 转换编码凭证
+            byte[] encodedBytes = Base64.getEncoder().encode(BASIC.getBytes(StandardCharsets.UTF_8));
+            String encodedCredentials = new String(encodedBytes, StandardCharsets.UTF_8);
+            headers.put("Authorization", " Basic " + encodedCredentials);
+            headers.put("Content-Type", "application/json");
+            HttpResponse response = HttpUtilsOauth2.doPost(URL, "/oauth2/token", "post", headers, map, new HashMap<>());
+            //2、处理
+            if (response.getStatusLine().getStatusCode() == 200) {
+                // 得到code换取token结果
+                String tokenJSON = EntityUtils.toString(response.getEntity());
+                Map<String, Object> tokenMap = JSONObject.parse(tokenJSON);
+                // 封装请求用户信息请求头
+                Map<String, String> getUserHeaders = new HashMap<>();
+                getUserHeaders.put("Authorization", " Bearer " + tokenMap.get("access_token"));
+//                getUserHeaders.put("Content-Type", "application/json");
+                HttpResponse userResponse = HttpUtilsOauth2.doGet(URL, "/user/login", "get", getUserHeaders, new HashMap<>());
+                if (userResponse.getStatusLine().getStatusCode() == 200) {
+                    // 得到当前登录用户信息
+                    String userJson = EntityUtils.toString(userResponse.getEntity());
+                    Map<String, Object> retUserMap = JSONObject.parse(userJson);
+                    String usernmae = "kjjt01";
+                    Map<String, Object> data = (Map<String, Object>) retUserMap.get("data");
+                    data.get("username");
+                    if (null == data.get("companyTenant")) {
+                        // ((Map) data.get("companyTenant")).get("tenantcode").toString();
+                        String tenantCode = "kjjt01";
+                        byte[] userInfo = Base64.getEncoder().encode((tenantCode + "^_^" + usernmae + "^_^" + System.currentTimeMillis() / 1000).getBytes(StandardCharsets.UTF_8));
+                        String retUserInfo = new String(userInfo, StandardCharsets.UTF_8);
+                        return "redirect:" + REDIRECT_URL + "/redirectAuth?bWVz=" + retUserInfo;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            System.out.println(e);
+            // 异常处理
+            return "redirect:" + REDIRECT_URL + "/401";
+        }
+        // 授权失败处理
+        return "redirect:" + REDIRECT_URL + "/401";
+    }
+
+    @ResponseBody
+    @GetMapping("/authorize")
+    public AjaxResult authorize() {
+        return AjaxResult.success("认证中心", URL + "/oauth2/authorize?" + "response_type=code" + "&client_id=toolmes" + "&scope=openid" + "&redirect_uri=" + CALLBACK);
+    }
+}
+

+ 13 - 0
zkqy-admin/src/main/resources/application.yml

@@ -150,3 +150,16 @@ parameter:
     PROCESS_ENGINE_IP: http://192.168.110.83:8055/dataSource/changeDataSource
     #数据引擎初始化数据库表接口地址
     DATA_ENGINE_INITDATABASE_IP: http://192.168.110.83:8099/tableInfo/initDatabase
+
+
+OpenAuthorization2:
+  # 工联院单点登录信息
+  GLY:
+    # 单点获取code、token、userinfo主机地址
+    URL: http://dljp.dev.feysh.com:30159
+    # 本系统标识 Base64
+    BASIC: toolmes:123456
+    # 重定向本系统主机地址
+    REDIRECT_URL: http://192.168.110.52:1024
+    # 回调地址
+    CALLBACK: https://db399361fp97.vicp.fun/oauth/callback

+ 12 - 7
zkqy-common/pom.xml

@@ -52,19 +52,19 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
-  
+
         <!-- JSON工具类 -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
-        
+
         <!-- 动态数据源 -->
-		<dependency>
-			<groupId>com.baomidou</groupId>
-			<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
-			<version>3.5.2</version>
-		</dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+            <version>3.5.2</version>
+        </dependency>
 
         <!-- 阿里JSON解析器 -->
         <dependency>
@@ -144,6 +144,11 @@
             <artifactId>ant</artifactId>
             <version>1.9.1</version>
         </dependency>
+        <!--HTTP-->
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 325 - 0
zkqy-common/src/main/java/com/zkqy/common/utils/http/HttpUtilsOauth2.java

@@ -0,0 +1,325 @@
+package com.zkqy.common.utils.http;
+
+import com.zkqy.common.utils.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author: monkey
+ * @createTime: 2023-08-20 09:33
+ **/
+public class HttpUtilsOauth2 {
+
+    /**
+     * get
+     *
+     * @param host
+     * @param path
+     * @param method
+     * @param headers
+     * @param querys
+     * @return
+     * @throws Exception
+     */
+    public static HttpResponse doGet(String host, String path, String method,
+                                     Map<String, String> headers,
+                                     Map<String, String> querys)
+            throws Exception {
+        HttpClient httpClient = wrapClient(host);
+
+        HttpGet request = new HttpGet(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+
+        return httpClient.execute(request);
+    }
+
+    /**
+     * post form
+     *
+     * @param host
+     * @param path
+     * @param method
+     * @param headers
+     * @param querys
+     * @param bodys
+     * @return
+     * @throws Exception
+     */
+    public static HttpResponse doPost(String host, String path, String method,
+                                      Map<String, String> headers,
+                                      Map<String, String> querys,
+                                      Map<String, String> bodys)
+            throws Exception {
+        HttpClient httpClient = wrapClient(host);
+
+        HttpPost request = new HttpPost(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (bodys.size()!=0&&bodys != null) {
+            List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
+
+            for (String key : bodys.keySet()) {
+                nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
+            }
+            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
+            formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
+            request.setEntity(formEntity);
+        }
+
+        return httpClient.execute(request);
+    }
+
+    /**
+     * Post String
+     *
+     * @param host
+     * @param path
+     * @param method
+     * @param headers
+     * @param querys
+     * @param body
+     * @return
+     * @throws Exception
+     */
+    public static HttpResponse doPost(String host, String path, String method,
+                                      Map<String, String> headers,
+                                      Map<String, String> querys,
+                                      String body)
+            throws Exception {
+        HttpClient httpClient = wrapClient(host);
+
+        HttpPost request = new HttpPost(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (StringUtils.isNotNull(body)) {
+            request.setEntity(new StringEntity(body, "utf-8"));
+        }
+
+        return httpClient.execute(request);
+    }
+
+    /**
+     * Post stream
+     *
+     * @param host
+     * @param path
+     * @param method
+     * @param headers
+     * @param querys
+     * @param body
+     * @return
+     * @throws Exception
+     */
+    public static HttpResponse doPost(String host, String path, String method,
+                                      Map<String, String> headers,
+                                      Map<String, String> querys,
+                                      byte[] body)
+            throws Exception {
+        HttpClient httpClient = wrapClient(host);
+
+        HttpPost request = new HttpPost(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (body != null) {
+            request.setEntity(new ByteArrayEntity(body));
+        }
+
+        return httpClient.execute(request);
+    }
+
+    /**
+     * Put String
+     *
+     * @param host
+     * @param path
+     * @param method
+     * @param headers
+     * @param querys
+     * @param body
+     * @return
+     * @throws Exception
+     */
+    public static HttpResponse doPut(String host, String path, String method,
+                                     Map<String, String> headers,
+                                     Map<String, String> querys,
+                                     String body)
+            throws Exception {
+        HttpClient httpClient = wrapClient(host);
+
+        HttpPut request = new HttpPut(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (StringUtils.isNotBlank(body)) {
+            request.setEntity(new StringEntity(body, "utf-8"));
+        }
+
+        return httpClient.execute(request);
+    }
+
+    /**
+     * Put stream
+     *
+     * @param host
+     * @param path
+     * @param method
+     * @param headers
+     * @param querys
+     * @param body
+     * @return
+     * @throws Exception
+     */
+    public static HttpResponse doPut(String host, String path, String method,
+                                     Map<String, String> headers,
+                                     Map<String, String> querys,
+                                     byte[] body)
+            throws Exception {
+        HttpClient httpClient = wrapClient(host);
+
+        HttpPut request = new HttpPut(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+
+        if (body != null) {
+            request.setEntity(new ByteArrayEntity(body));
+        }
+
+        return httpClient.execute(request);
+    }
+
+    /**
+     * Delete
+     *
+     * @param host
+     * @param path
+     * @param method
+     * @param headers
+     * @param querys
+     * @return
+     * @throws Exception
+     */
+    public static HttpResponse doDelete(String host, String path, String method,
+                                        Map<String, String> headers,
+                                        Map<String, String> querys)
+            throws Exception {
+        HttpClient httpClient = wrapClient(host);
+
+        HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
+        for (Map.Entry<String, String> e : headers.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+
+        return httpClient.execute(request);
+    }
+
+    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
+        StringBuilder sbUrl = new StringBuilder();
+        sbUrl.append(host);
+        if (!StringUtils.isBlank(path)) {
+            sbUrl.append(path);
+        }
+        if (null != querys) {
+            StringBuilder sbQuery = new StringBuilder();
+            for (Map.Entry<String, String> query : querys.entrySet()) {
+                if (0 < sbQuery.length()) {
+                    sbQuery.append("&");
+                }
+                if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
+                    sbQuery.append(query.getValue());
+                }
+                if (!StringUtils.isBlank(query.getKey())) {
+                    sbQuery.append(query.getKey());
+                    if (!StringUtils.isBlank(query.getValue())) {
+                        sbQuery.append("=");
+                        sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
+                    }
+                }
+            }
+            if (0 < sbQuery.length()) {
+                sbUrl.append("?").append(sbQuery);
+            }
+        }
+
+        return sbUrl.toString();
+    }
+
+    private static HttpClient wrapClient(String host) {
+        HttpClient httpClient = new DefaultHttpClient();
+        if (host.startsWith("https://")) {
+            sslClient(httpClient);
+        }
+
+        return httpClient;
+    }
+
+    private static void sslClient(HttpClient httpClient) {
+        try {
+            SSLContext ctx = SSLContext.getInstance("TLS");
+            X509TrustManager tm = new X509TrustManager() {
+                @Override
+                public X509Certificate[] getAcceptedIssuers() {
+                    return null;
+                }
+
+                @Override
+                public void checkClientTrusted(X509Certificate[] xcs, String str) {
+
+                }
+
+                @Override
+                public void checkServerTrusted(X509Certificate[] xcs, String str) {
+
+                }
+            };
+            ctx.init(null, new TrustManager[]{tm}, null);
+            SSLSocketFactory ssf = new SSLSocketFactory(ctx);
+            ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+            ClientConnectionManager ccm = httpClient.getConnectionManager();
+            SchemeRegistry registry = ccm.getSchemeRegistry();
+            registry.register(new Scheme("https", 443, ssf));
+        } catch (KeyManagementException ex) {
+            throw new RuntimeException(ex);
+        } catch (NoSuchAlgorithmException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+
+}

+ 9 - 14
zkqy-framework/src/main/java/com/zkqy/framework/config/SecurityConfig.java

@@ -22,18 +22,17 @@ import com.zkqy.framework.security.handle.LogoutSuccessHandlerImpl;
 
 /**
  * spring security配置
- * 
+ *
  * @author zkqy
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
-public class SecurityConfig extends WebSecurityConfigurerAdapter
-{
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
     /**
      * 自定义用户认证逻辑
      */
     @Autowired
     private UserDetailsService userDetailsService;
-    
+
     /**
      * 认证失败处理类
      */
@@ -51,7 +50,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Autowired
     private JwtAuthenticationTokenFilter authenticationTokenFilter;
-    
+
     /**
      * 跨域过滤器
      */
@@ -72,8 +71,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Bean
     @Override
-    public AuthenticationManager authenticationManagerBean() throws Exception
-    {
+    public AuthenticationManager authenticationManagerBean() throws Exception {
         return super.authenticationManagerBean();
     }
 
@@ -93,8 +91,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * authenticated       |   用户登录后可访问
      */
     @Override
-    protected void configure(HttpSecurity httpSecurity) throws Exception
-    {
+    protected void configure(HttpSecurity httpSecurity) throws Exception {
         // 注解标记允许匿名访问的url
         ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
         permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
@@ -111,7 +108,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register", "/captchaImage","/loginAdmin","/isTenantExist").permitAll()
+                .antMatchers("/login", "/register", "/captchaImage", "/loginAdmin", "/isTenantExist", "/oauth/callback", "/Oauth2Login/**", "/authorize").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
@@ -132,8 +129,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * 强散列哈希加密实现
      */
     @Bean
-    public BCryptPasswordEncoder bCryptPasswordEncoder()
-    {
+    public BCryptPasswordEncoder bCryptPasswordEncoder() {
         return new BCryptPasswordEncoder();
     }
 
@@ -141,8 +137,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * 身份认证接口
      */
     @Override
-    protected void configure(AuthenticationManagerBuilder auth) throws Exception
-    {
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
         auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
     }
 }

+ 108 - 0
zkqy-framework/src/main/java/com/zkqy/framework/web/service/SysLoginService.java

@@ -5,14 +5,18 @@ import javax.annotation.Resource;
 import cn.hutool.core.util.CharsetUtil;
 import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
 import cn.hutool.crypto.symmetric.SymmetricCrypto;
+import com.zkqy.common.core.domain.AjaxResult;
+import com.zkqy.common.core.domain.entity.DataSource;
 import com.zkqy.common.core.domain.entity.SysTenant;
 import com.zkqy.common.core.domain.model.LoginBody;
+import com.zkqy.system.service.IDataSourceService;
 import com.zkqy.system.service.impl.SysTenantServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 import com.zkqy.common.constant.CacheConstants;
 import com.zkqy.common.constant.Constants;
@@ -36,8 +40,11 @@ import com.zkqy.framework.security.context.AuthenticationContextHolder;
 import com.zkqy.system.service.ISysConfigService;
 import com.zkqy.system.service.ISysUserService;
 
+import java.nio.charset.StandardCharsets;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
+import java.util.Base64;
+import java.util.Collections;
 
 /**
  * 登录校验方法
@@ -64,6 +71,9 @@ public class SysLoginService {
     @Autowired
     private SysTenantServiceImpl sysTenantService;
 
+    @Autowired
+    private IDataSourceService iDataSourceService;
+
     /**
      * 登录验证
      *
@@ -112,6 +122,36 @@ public class SysLoginService {
         return tokenService.createToken(loginUser);
     }
 
+
+    /**
+     * 登录验证
+     *
+     * @param username 用户名
+     * @param password 密码
+     * @param code     验证码
+     * @param uuid     唯一标识
+     * @return 结果
+     */
+    public String loginOauth(String tenantCode, String userName) {
+        // 生成token对象
+        LoginUser loginUser = new LoginUser();
+        // 获取当前租户信息
+        SysTenant sysTenant = sysTenantService.selectSysTenantByTenantCode(tenantCode);
+        // 获取当前租户数据源信息
+        DataSource dataSource = iDataSourceService.selectById(sysTenant.getDatasourceId());
+        sysTenant.setDataSource(dataSource);
+        // 根据租户编号、用户名查询详细信息
+        SysUser sysUser = userService.selectUserInfoByTenantCode(tenantCode, userName);
+        sysUser.setTenant(sysTenant);
+        loginUser.setUser(sysUser);
+        // 创建一个Authentication对象
+        Authentication authentication = new UsernamePasswordAuthenticationToken(loginUser, null, Collections.emptyList());
+        // 将Authentication对象设置到SecurityContext中
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+        // 生成token
+        return tokenService.createToken(loginUser);
+    }
+
     /**
      * 校验验证码
      *
@@ -218,4 +258,72 @@ public class SysLoginService {
         }
         return "";
     }
+
+    public String checkTenantExpirationTimeOauth(LoginBody loginBody) {
+        // 拿到当前用户
+        SysUser user;
+        if (loginBody.getUsername().equals("admin")) {
+            user = userService.selectUserByUserName(loginBody.getUsername());
+        } else {
+            user = userService.selectUserByUserNameOauth(loginBody.getTenantID() + "¥¥¥" + loginBody.getUsername());
+        }
+
+        //拿到当前登录用户
+        if (!user.getUserName().equals("admin")) {
+            //根据租户id查询租户信息
+            SysTenant sysTenant = sysTenantService.selectSysTenantByTenantId(user.getTenantId());
+            if (sysTenant == null) {
+                return "未有此租户信息";
+            }
+            if (sysTenant.getTenantExpirationTime() == null || sysTenant.getTenantExpirationTime().isEmpty()) {
+                return "该用户租户信息并未激活";
+            }
+            SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.DES, "sgEsnN6QWq8W7j5H01020304".getBytes());
+            //当前时间
+            LocalDateTime now = LocalDateTime.now();
+            long nowSecond = now.toEpochSecond(ZoneOffset.ofHours(8));
+            //到期时间
+            String LastActiveTimeStr = symmetricCrypto.decryptStr(sysTenant.getTenantExpirationTime(), CharsetUtil.CHARSET_UTF_8);
+            LocalDateTime LastActiveDateTime = DateUtils.toLocalDateTime(LastActiveTimeStr, "yyyy-MM-dd HH:mm:ss");
+            long expirationTimeSecond = LastActiveDateTime.toEpochSecond(ZoneOffset.ofHours(8));
+            //计算时间戳
+            long difference = expirationTimeSecond - nowSecond; //相差的时间数 后边减前边
+            //如果是负数证明已经过期了
+            if (difference < 0) {
+                return "该用户租户信息已过期";
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 不加验证码登录
+     *
+     * @param username 用户名
+     * @param password 密码
+     * @param uuid     唯一标识
+     * @return 结果
+     */
+    public String loginNoCode(String username, String password, String uuid) {
+        // 用户验证
+        Authentication authentication = null;
+        try {
+            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+            authentication = authenticationManager
+                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
+        } catch (Exception e) {
+            if (e instanceof BadCredentialsException) {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                throw new UserPasswordNotMatchException();
+            } else {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
+                throw new ServiceException(e.getMessage());
+            }
+        }
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        recordLoginInfo(loginUser.getUserId());
+        // 生成token
+        return tokenService.createToken(loginUser);
+    }
 }

+ 5 - 0
zkqy-framework/src/main/java/com/zkqy/framework/web/service/TokenService.java

@@ -71,6 +71,11 @@ public class TokenService {
                 }
                 String userKey = getTokenKey(uuid);
                 LoginUser user = redisCache.getCacheObject(userKey);
+                if (user.getUserId()==null){
+                    user.setUserId(user.getUser().getUserId());
+                    user.setDeptId(user.getDeptId());
+                    user.setTenantId(user.getTenantId());
+                }
                 return user;
             } catch (Exception e) {
             }

+ 36 - 16
zkqy-system/src/main/java/com/zkqy/system/mapper/SysUserMapper.java

@@ -7,14 +7,13 @@ import com.zkqy.common.core.domain.entity.SysUser;
 
 /**
  * 用户表 数据层
- * 
+ *
  * @author zkqy
  */
-public interface SysUserMapper
-{
+public interface SysUserMapper {
     /**
      * 根据条件分页查询用户列表
-     * 
+     *
      * @param sysUser 用户信息
      * @return 用户信息集合信息
      */
@@ -22,7 +21,7 @@ public interface SysUserMapper
 
     /**
      * 根据条件分页查询已配用户角色列表
-     * 
+     *
      * @param user 用户信息
      * @return 用户信息集合信息
      */
@@ -30,7 +29,7 @@ public interface SysUserMapper
 
     /**
      * 根据条件分页查询未分配用户角色列表
-     * 
+     *
      * @param user 用户信息
      * @return 用户信息集合信息
      */
@@ -38,7 +37,7 @@ public interface SysUserMapper
 
     /**
      * 通过用户名查询用户
-     * 
+     *
      * @param userName 用户名
      * @return 用户对象信息
      */
@@ -53,9 +52,18 @@ public interface SysUserMapper
      */
     public SysUser selectUserByTenantInfo(@Param("tenantId") String tenantId, @Param("userName") String userName);
 
+    /**
+     * 通过租户信息查询用户
+     *
+     * @param tenantId 租户id
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    public SysUser selectUserByTenantInfoOauth(@Param("tenantCode") String tenantId, @Param("userName") String userName);
+
     /**
      * 通过用户ID查询用户
-     * 
+     *
      * @param userId 用户ID
      * @return 用户对象信息
      */
@@ -63,7 +71,7 @@ public interface SysUserMapper
 
     /**
      * 新增用户信息
-     * 
+     *
      * @param user 用户信息
      * @return 结果
      */
@@ -71,7 +79,7 @@ public interface SysUserMapper
 
     /**
      * 修改用户信息
-     * 
+     *
      * @param user 用户信息
      * @return 结果
      */
@@ -79,16 +87,16 @@ public interface SysUserMapper
 
     /**
      * 修改用户头像
-     * 
+     *
      * @param userName 用户名
-     * @param avatar 头像地址
+     * @param avatar   头像地址
      * @return 结果
      */
     public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
 
     /**
      * 重置用户密码
-     * 
+     *
      * @param userName 用户名
      * @param password 密码
      * @return 结果
@@ -97,7 +105,7 @@ public interface SysUserMapper
 
     /**
      * 通过用户ID删除用户
-     * 
+     *
      * @param userId 用户ID
      * @return 结果
      */
@@ -105,7 +113,7 @@ public interface SysUserMapper
 
     /**
      * 批量删除用户信息
-     * 
+     *
      * @param userIds 需要删除的用户ID
      * @return 结果
      */
@@ -113,7 +121,7 @@ public interface SysUserMapper
 
     /**
      * 校验用户名称是否唯一
-     * 
+     *
      * @param userName 用户名称
      * @return 结果
      */
@@ -147,6 +155,7 @@ public interface SysUserMapper
 
     /**
      * 查询这组用户中是否存在真实用户
+     *
      * @param userIds
      * @return
      */
@@ -154,8 +163,19 @@ public interface SysUserMapper
 
     /**
      * 根据账号查询当前库中存在多少相同账号
+     *
      * @param userName 账号
      * @return
      */
     int queryCountUserName(String userName);
+
+
+    /**
+     * 查询当前租户用户信息
+     *
+     * @param tenantCode 租户编号
+     * @param userName   用户名
+     * @return 用户对象信息
+     */
+    public SysUser selectUserInfoByTenantCode(@Param("tenantCode") String tenantCode, @Param("userName") String userName);
 }

+ 26 - 0
zkqy-system/src/main/java/com/zkqy/system/service/ISysUserService.java

@@ -2,6 +2,7 @@ package com.zkqy.system.service;
 
 import java.util.List;
 import com.zkqy.common.core.domain.entity.SysUser;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * 用户 业务层
@@ -42,6 +43,14 @@ public interface ISysUserService
      */
     public SysUser selectUserByUserName(String userName);
 
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    public SysUser selectUserByUserNameOauth(String userName);
+
     /**
      * 通过用户ID查询用户
      * 
@@ -74,6 +83,14 @@ public interface ISysUserService
      */
     public boolean checkUserNameUnique(SysUser user);
 
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public boolean checkUserNameUniqueSSO(SysUser user);
+
     /**
      * 校验手机号码是否唯一
      *
@@ -222,4 +239,13 @@ public interface ISysUserService
      * @return
      */
     boolean isExistUser(String userName);
+
+    /**
+     * 查询当前租户用户信息
+     *
+     * @param tenantCode 租户编号
+     * @param userName   用户名
+     * @return 用户对象信息
+     */
+    public SysUser selectUserInfoByTenantCode(String tenantCode, String userName);
 }

+ 38 - 1
zkqy-system/src/main/java/com/zkqy/system/service/impl/SysUserServiceImpl.java

@@ -112,7 +112,21 @@ public class SysUserServiceImpl implements ISysUserService {
             return userMapper.selectUserByTenantInfo(info[0], info[1]);
         }
     }
-
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    @Override
+    public SysUser selectUserByUserNameOauth(String userName) {
+        if (userName.equals("admin")) {
+            return userMapper.selectUserByUserName(userName);
+        } else {
+            String info[] = userName.split("¥¥¥");
+            return userMapper.selectUserByTenantInfoOauth(info[0], info[1]);
+        }
+    }
     /**
      * 通过用户ID查询用户
      *
@@ -170,6 +184,24 @@ public class SysUserServiceImpl implements ISysUserService {
         return UserConstants.UNIQUE;
     }
 
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param ssoUser 用户信息
+     * @return 结果
+     */
+    @Override
+    public boolean checkUserNameUniqueSSO(SysUser ssoUser) {
+        Long userId = StringUtils.isNull(ssoUser.getUserId()) ? -1L : ssoUser.getUserId();
+        // ssoUser.getTenantId().toString(),
+        SysUser info = userMapper.checkUserNameUnique(ssoUser.getUserName());
+        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
+
     /**
      * 校验手机号码是否唯一
      *
@@ -514,4 +546,9 @@ public class SysUserServiceImpl implements ISysUserService {
         }
         return false;
     }
+
+    @Override
+    public SysUser selectUserInfoByTenantCode(String tenantCode, String userName) {
+        return userMapper.selectUserInfoByTenantCode(tenantCode, userName);
+    }
 }

+ 12 - 0
zkqy-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -244,11 +244,18 @@
         <include refid="selectUserVo"/>
         where u.user_name = #{userName} and u.del_flag = '0'
     </select>
+
+
     <select id="selectUserByTenantInfo" parameterType="String" resultMap="SysUserResult">
         <include refid="selectUserVo"/>
         where u.tenant_id = #{tenantId} and u.user_name = #{userName} and u.del_flag = '0'
     </select>
 
+    <select id="selectUserByTenantInfoOauth" parameterType="String" resultMap="SysUserResult">
+        <include refid="selectUserVo"/>
+        where te.tenant_code = #{tenantCode} and u.user_name = #{userName} and u.del_flag = '0'
+    </select>
+
     <select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
         <include refid="selectUserVo"/>
         where u.user_id = #{userId}
@@ -389,4 +396,9 @@
           and del_flag = '0'
     </select>
 
+    <select id="selectUserInfoByTenantCode" parameterType="String" resultMap="SysUserResult">
+        <include refid="selectUserVo"/>
+        where te.tenant_code = #{tenantCode} and u.user_name = #{userName} and u.del_flag = '0'
+    </select>
+
 </mapper>