liusheng
7 小时以前 a4bc7ba7a708cf2867f3027f593ef72c0d8acf78
单点登陆白名单访问功能
已添加3个文件
已修改3个文件
165 ■■■■ 文件已修改
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hanler/IpWhitelistInterceptor.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/WebConfig.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/IpWhitelist.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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)) {
                //获取请求的IP,判断是不是在白名单中
                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;
    }
}
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 @@
    }
    /**
     * å•点登录方法
     * å•点登录方法(需要配置IP白名单)
     * éœ€è¦åœ¨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 {
        // ç”Ÿæˆæˆ–获取token
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("/**");
    }
}
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>
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 {
}
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -108,9 +108,10 @@
                // è¿‡æ»¤è¯·æ±‚
                .authorizeRequests()
                // å¯¹äºŽç™»å½•login æ³¨å†Œregister éªŒè¯ç captchaImage å…è®¸åŒ¿åè®¿é—®
                .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();