何在RuoYi-Plus项目中新增IP白名单功能
在实际开发中,我们经常会遇到某些功能只允许特定IP地址访问的场景。RuoYi-Plus项目中,新增IP白名单功能可以通过自定义注解和AOP拦截器轻松实现。本文将详细介绍如何在RuoYi-Plus项目中新增IP白名单功能,并进行测试。
目录结构
- IpWhitelist.java:自定义注解,用于标记允许访问的IP地址
- IpWhitelistAspect.java:AOP拦截器,负责IP白名单校验
- IpWhiteConfig.java:配置文件,加载拦截器
- pom.xml:依赖配置
- TestIpWhilteListController.java:测试控制器,用于验证白名单功能
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异常,并返回相应的错误信息。
总结
通过以上步骤,我们在RuoYi-Plus项目中成功实现了IP白名单功能。这个功能可以有效地限制某些敏感接口的访问权限,确保只有特定的IP地址能够访问,提高了系统的安全性。
扩展:
- 可以通过管理界面动态修改Redis中的IP白名单,实现灵活的白名单管理。
- 结合日志系统,监控和记录所有访问白名单受限接口的IP地址,提升安全监控能力。