From a4bc7ba7a708cf2867f3027f593ef72c0d8acf78 Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期六, 06 九月 2025 17:46:14 +0800
Subject: [PATCH] 单点登陆白名单访问功能

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/hanler/IpWhitelistInterceptor.java |   82 +++++++++++++++++++++++++++
 ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WebConfig.java                    |   22 +++++++
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java     |   41 +++++++------
 ruoyi-common/src/main/java/com/ruoyi/common/annotation/IpWhitelist.java               |   10 +++
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java          |    5 +
 ruoyi-common/pom.xml                                                                  |    5 +
 6 files changed, 144 insertions(+), 21 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/hanler/IpWhitelistInterceptor.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/hanler/IpWhitelistInterceptor.java
new file mode 100644
index 0000000..277238a
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/hanler/IpWhitelistInterceptor.java
@@ -0,0 +1,82 @@
+package com.ruoyi.web.controller.hanler;
+
+import com.ruoyi.common.annotation.IpWhitelist;
+import com.ruoyi.system.domain.SysConfig;
+import com.ruoyi.system.mapper.SysConfigMapper;
+import org.apache.commons.net.util.SubnetUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Component
+public class IpWhitelistInterceptor implements HandlerInterceptor {
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        System.out.println("澶勭悊鍣ㄧ被: " + handler.getClass().getName());
+        if (handler instanceof HandlerMethod) {
+            HandlerMethod handlerMethod = (HandlerMethod) handler;
+            if (handlerMethod.hasMethodAnnotation(IpWhitelist.class)) {
+                //鑾峰彇璇锋眰鐨処P锛屽垽鏂槸涓嶆槸鍦ㄧ櫧鍚嶅崟涓�
+                String clientIp = getClientIp(request);
+                if (!isIpInWhitelist(clientIp)) {
+                    response.setStatus(HttpStatus.FORBIDDEN.value());
+                    response.getWriter().write("Access denied: IP address not whitelisted");
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private String getClientIp(HttpServletRequest request) {
+        String ip = request.getHeader("X-Forwarded-For");
+        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        return ip;
+    }
+
+    private boolean isIpInWhitelist(String ip) {
+        try {
+            SysConfig config = new SysConfig();
+            config.setConfigKey("sys.ip.whitelist");
+            SysConfig sysConfig = sysConfigMapper.selectConfig(config);
+            List<String> whitelistIps = Arrays.asList(sysConfig.getConfigValue().split(","));
+            for (String whitelist : whitelistIps) {
+                if (whitelist.contains("/")) {
+                    // CIDR鏍煎紡
+                    SubnetUtils subnetUtils = new SubnetUtils(whitelist);
+                    if (subnetUtils.getInfo().isInRange(ip)) {
+                        return true;
+                    }
+                } else {
+                    // 鍗曚釜IP
+                    if (whitelist.equals(ip)) {
+                        return true;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return false;
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
index a5e2dd6..0ebc693 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -1,11 +1,12 @@
 package com.ruoyi.web.controller.system;
 
-import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.common.annotation.IpWhitelist;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysMenu;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.LoginBody;
+import com.ruoyi.common.exception.base.BaseException;
 import com.ruoyi.common.utils.RSAPublicKeyExample;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
@@ -16,11 +17,15 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.view.RedirectView;
 
-import javax.annotation.security.PermitAll;
 import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
 import java.io.IOException;
+import java.net.URI;
 import java.util.List;
 import java.util.Set;
 
@@ -67,35 +72,33 @@
     }
 
     /**
-     * 鍗曠偣鐧诲綍鏂规硶
+     * 鍗曠偣鐧诲綍鏂规硶(闇�瑕侀厤缃甀P鐧藉悕鍗�)
+     * 闇�瑕佸湪sys_config琛ㄧ殑sys.ip.whitelis涓紝鍔犲叆IP鎵嶈兘璁块棶璇ユ柟娉�
      *
-     * @param loginBody 鍗曠偣鐧诲綍淇℃伅
      * @return 缁撴灉
      */
-    @PostMapping("/SSOLogin")
-    public AjaxResult SSOLogin(@RequestBody LoginBody loginBody) {
-        AjaxResult ajax = AjaxResult.success();
+    @IpWhitelist
+    @GetMapping("/SSOLogin")
+    public RedirectView SSOLogin(@RequestParam String userName, @RequestParam String orgid, @RequestParam(required = false) String deptId) {
+        RedirectView redirectView = new RedirectView();
         // 鐢熸垚浠ょ墝
-        if (StringUtils.isEmpty(loginBody.getUsername()) || StringUtils.isEmpty(loginBody.getOrgid())) {
-            return AjaxResult.error("鐢ㄦ埛鍚嶆垨缁勭粐鏈烘瀯鎴栭儴闂ㄤ笉鑳戒负绌�");
+        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(orgid)) {
+            throw new BaseException("鐢ㄦ埛鍚嶆垨缁勭粐鏈烘瀯鎴栭儴闂ㄤ笉鑳戒负绌�");
         }
-
-        if (StringUtils.isEmpty(loginBody.getDeptId())) {
-            loginBody.setDeptId(null);
-        }
-        String userName = loginBody.getUsername();
         if (isEncryp == 1) {
             RSAPublicKeyExample rsaPublicKeyExample = new RSAPublicKeyExample();
-            userName = rsaPublicKeyExample.decryptedData(loginBody.getUsername(), pri_key);
+            userName = rsaPublicKeyExample.decryptedData(userName, pri_key);
         }
-        String token = loginService.loginByUserName(userName + "&" + loginBody.getOrgid() + "&" + loginBody.getDeptId());
+        String token = loginService.loginByUserName(userName + "&" + orgid + "&" + deptId);
         if (StringUtils.isEmpty(token)) {
-            return AjaxResult.error("鐧婚檰澶辫触");
+            throw new BaseException("鐧婚檰澶辫触");
         }
-        ajax.put(Constants.TOKEN, token);
-        return ajax;
+        redirectView.setUrl("http://127.0.0.1:8091/loginSSO?token=" + token + "&orgid=" + orgid + "&orgname=''" + "&ZuHuID=''&deptCode=''&redirect=''");
+        redirectView.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
+        return redirectView;
     }
 
+
     @GetMapping("/getToken")
     public void getToken(HttpServletResponse response) throws IOException {
         // 鐢熸垚鎴栬幏鍙杢oken
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WebConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WebConfig.java
new file mode 100644
index 0000000..ed2c101
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WebConfig.java
@@ -0,0 +1,22 @@
+package com.ruoyi.web.core.config;
+
+import com.ruoyi.web.controller.hanler.IpWhitelistInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+  @Autowired
+  private IpWhitelistInterceptor methodIpWhitelistInterceptor;
+
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(methodIpWhitelistInterceptor)
+                .addPathPatterns("/**");
+    }
+
+}
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index a663e7e..f1bbbb7 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -211,6 +211,11 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
         </dependency>
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+            <version>3.8.0</version>
+        </dependency>
 
     </dependencies>
 
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/IpWhitelist.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/IpWhitelist.java
new file mode 100644
index 0000000..5aad150
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/IpWhitelist.java
@@ -0,0 +1,10 @@
+package com.ruoyi.common.annotation;
+
+import java.lang.annotation.*;
+
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface IpWhitelist {
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 921dff6..ea1a17b 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -108,9 +108,10 @@
                 // 杩囨护璇锋眰
                 .authorizeRequests()
                 // 瀵逛簬鐧诲綍login 娉ㄥ唽register 楠岃瘉鐮乧aptchaImage 鍏佽鍖垮悕璁块棶
-                .antMatchers("/login", "/register", "/captchaImage", "/qrcode/generateStaticHtml", "/qrcode/getQRcode", "/qrcode/getFormDate", "/chat", "/system/file/admin/uploadFile", "/smartor/dingtalk/sendNotification", "/patient/read/patientInfo", "/socket", "/API_ESB_Service", "/API_ESB_Service/Run", "/magic/web/**", "/smartor/serviceSubtask/phoneCallBack", "/smartor/serviceSubtask/taskPull", "/smartor/serviceSubtask/phoneCallBackYQ", "/smartor/robot/callstatus", "/smartor/robot/aidialog", "/smartor/robot/cdrinfo", "/getToken", "/smartor/subtaskAnswer/getQuestionCache", "/smartor/subtaskAnswer/saveQuestionCache", "/smartor/servicetask/getScriptInfoByCondition", "/smartor/subtaskAnswer/saveQuestionAnswer", "/smartor/import/download", "/smartor/serviceSubtask/recordAccept", "/smartor/outPath/getInfoByParam", "/smartor/serviceExternal/addDeptInfo", "/smartor/serviceExternal/**", "/sso/**","/smartor/sltdHealthcareRecord/**").permitAll()
+                .antMatchers("/login", "/register", "/captchaImage", "/qrcode/generateStaticHtml", "/qrcode/getQRcode", "/qrcode/getFormDate", "/chat", "/system/file/admin/uploadFile", "/smartor/dingtalk/sendNotification", "/patient/read/patientInfo", "/socket", "/API_ESB_Service", "/API_ESB_Service/Run", "/magic/web/**", "/smartor/serviceSubtask/phoneCallBack", "/smartor/serviceSubtask/taskPull", "/smartor/serviceSubtask/phoneCallBackYQ", "/smartor/robot/callstatus", "/smartor/robot/aidialog", "/smartor/robot/cdrinfo", "/getToken", "/smartor/subtaskAnswer/getQuestionCache", "/smartor/subtaskAnswer/saveQuestionCache", "/smartor/servicetask/getScriptInfoByCondition", "/smartor/subtaskAnswer/saveQuestionAnswer", "/smartor/import/download", "/smartor/serviceSubtask/recordAccept", "/smartor/outPath/getInfoByParam", "/smartor/serviceExternal/addDeptInfo", "/smartor/serviceExternal/**", "/sso/**","/smartor/sltdHealthcareRecord/**","/smartor/servicetask/getScriptByCondition","/smartor/subtaskAnswer/saveMYDQuestionAnswer").permitAll()
+                .antMatchers(HttpMethod.GET, "/SSOLogin/**").permitAll()
                 // 闈欐�佽祫婧愶紝鍙尶鍚嶈闂�
-                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
+                .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**","/getDept/*").permitAll().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
                 .antMatchers("/smartor/organization/list").permitAll()
                 // 闄や笂闈㈠鐨勬墍鏈夎姹傚叏閮ㄩ渶瑕侀壌鏉冭璇�
                 .anyRequest().authenticated().and().headers().frameOptions().disable();

--
Gitblit v1.9.3