RuoYI-Plus新增ip白名单功能

1,016 阅读3分钟

何在RuoYi-Plus项目中新增IP白名单功能

在实际开发中,我们经常会遇到某些功能只允许特定IP地址访问的场景。RuoYi-Plus项目中,新增IP白名单功能可以通过自定义注解和AOP拦截器轻松实现。本文将详细介绍如何在RuoYi-Plus项目中新增IP白名单功能,并进行测试。

目录结构

  • IpWhitelist.java:自定义注解,用于标记允许访问的IP地址
  • IpWhitelistAspect.java:AOP拦截器,负责IP白名单校验
  • IpWhiteConfig.java:配置文件,加载拦截器
  • pom.xml:依赖配置
  • TestIpWhilteListController.java:测试控制器,用于验证白名单功能

PixPin_2024-09-13_11-25-37.png

1. 自定义注解 IpWhitelist

首先,我们需要定义一个注解@IpWhitelist,用于标记哪些方法需要进行IP白名单校验。

IpWhitelist.java

/**  
 * 自定义注解:只有 IP 白名单内的服务器才可以访问  
 */  
@Target(ElementType.METHOD) // 可以注解在方法上  
@Retention(RetentionPolicy.RUNTIME) // 运行时有效  
@Documented  
public @interface IpWhitelist {  
}

说明:

  • @Target(ElementType.METHOD):表明该注解可以作用于方法上。
  • @Retention(RetentionPolicy.RUNTIME):表示该注解在运行时有效。
  • @Documented:标识该注解是否生成javadoc文档。

2. AOP拦截器 IpWhitelistAspect

接下来,我们通过AOP拦截器来实现IP白名单校验。拦截带有@IpWhitelist注解的方法,并检查请求IP是否在白名单内。

IpWhitelistAspect.java

/**  
 * AOP 拦截器:检查 IP 白名单  
 */  
@Aspect  
@Component  
@RequiredArgsConstructor  
@Slf4j  
public class IpWhitelistAspect {  
  
    /**  
     * 拦截所有带有 @IpWhitelist 注解的方法,执行 IP 白名单检查  
     */  
    @Before("@annotation(ipWhitelist)")  
    public void checkIpWhitelist(IpWhitelist ipWhitelist) {  
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();  
        String clientIp = request.getRemoteAddr();  // 获取客户端 IP  
        // 获取 IP 白名单  
        Set<String> whiteList = getWhiteListFromRedis();  
  
        // 如果客户端 IP 不在白名单中,则抛出异常  
        if (!whiteList.contains(clientIp)) {  
            log.warn("访问IP不在白名单中,访问被拒绝: {}", clientIp);  
            throw new SecurityException("IP地址不在白名单中,禁止访问");  
        }  
    }  
  
    /**  
     * 从 Redis 中获取 IP 白名单  
     */  
    private Set<String> getWhiteListFromRedis() {  
        // 假设 Redis 中的 key 为 'ipWhiteList'        
        Set<String> whiteList = RedisUtils.getCacheSet(CacheNames.IP_WHITELIST);  
        return whiteList != null ? whiteList : Collections.emptySet();  
    }  
}

说明:

  • @Before("@annotation(ipWhitelist)"):拦截所有带有@IpWhitelist注解的方法。
  • getRemoteAddr():获取客户端请求的IP地址。
  • getWhiteListFromRedis():从Redis中获取IP白名单,假设Redis中存储的key为ipWhiteList
  • 当客户端IP不在白名单中时,抛出SecurityException异常,阻止访问。

3. 配置类 IpWhiteConfig

为了让AOP拦截器生效,我们需要通过配置类加载IpWhitelistAspect

IpWhiteConfig.java

/**  
 * 幂等功能配置  
 *  
 * @author Lion Li  
 */
@AutoConfiguration(after = RedisConfiguration.class)  
public class IpWhiteConfig {  
  
    @Bean  
    public IpWhitelistAspect ipWhitelistAspect() {  
        return new IpWhitelistAspect();  
    }  
  
}

说明:

  • @AutoConfiguration:自动配置类,指定该配置在RedisConfiguration之后加载。
  • ipWhitelistAspect():声明AOP拦截器的Bean,并注入到Spring容器中。

4. pom.xml中添加依赖

为使项目支持Redis操作,我们需要在pom.xml中引入cf-common-redis依赖:

pox.xml

<dependency>            
	<groupId>com.cf</groupId>  
    <artifactId>cf-common-redis</artifactId>  
</dependency>  

同时别忘了在RuoYi-common中添加模块依赖:<module>cf-common-ipWhite</module>

5. 测试控制器 TestIpWhilteListController

为了验证IP白名单功能的有效性,我们创建一个测试控制器,并在方法上使用@IpWhitelist注解。

/**  
 * ip白名单测试  
 * 请先阅读文档 否则无法使用  
 *  
 * @author YCH  
 * @version 4.2.0  
 */@Validated  
@RequiredArgsConstructor  
@RestController  
@RequestMapping("IpWhitelist")  
public class TestIpWhilteListController {  
    /**  
     * ip白名单测试  
     *  
    */    
    @GetMapping  
	@SaIgnore    
	@IpWhitelist    
	public R<Object> ipWhitelistTest() {  
        return R.ok();  
    }  
  
}

说明:

  • @GetMapping:定义一个GET请求接口。
  • @SaIgnore:忽略认证检查,专注于IP白名单功能测试。
  • @IpWhitelist:标记此接口需要进行IP白名单校验。

6. 测试效果

当客户端请求的IP地址在Redis的白名单中时,接口会正常返回200 OK响应。否则,将会抛出SecurityException异常,并返回相应的错误信息。

PixPin_2024-09-13_13-06-09.png

PixPin_2024-09-13_13-05-10.png

总结

通过以上步骤,我们在RuoYi-Plus项目中成功实现了IP白名单功能。这个功能可以有效地限制某些敏感接口的访问权限,确保只有特定的IP地址能够访问,提高了系统的安全性。

扩展:

  • 可以通过管理界面动态修改Redis中的IP白名单,实现灵活的白名单管理。
  • 结合日志系统,监控和记录所有访问白名单受限接口的IP地址,提升安全监控能力。