Ruoyi-Radius详解

Ruoyi-Radius详解


一、模块功能架构

核心目标:实现基于 RADIUS 协议的 AAA(认证、授权、计费)服务,与若依管理系统无缝集成,复用其用户体系与权限模型。
功能细分

  1. 认证(Authentication):校验用户凭证(用户名/密码)合法性。
  2. 授权(Authorization):动态返回用户网络权限属性(如VLAN、IP池、带宽策略)。
  3. 计费(Accounting):记录用户会话时长、流量消耗等计费信息。

gitee地址:https://gitee.com/fanshown/ruoyi-radius
访问地址:http://localhost:8090/index
portal认证地址:http://localhost:8090/portal/wlan/index

二、项目结构与核心代码实现
1. 依赖配置 (pom.xml)
<!-- 核心依赖 -->
<dependency>
    <groupId>org.tinyradius</groupId>
    <artifactId>jradius-core</artifactId>
    <version>1.1.8</version> <!-- RADIUS协议解析库 -->
</dependency>
<dependency>
    <groupId>com.ruoyi</groupId>
    <artifactId>ruoyi-common</artifactId> <!-- 若依基础模块 -->
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId> <!-- 安全认证 -->
</dependency>
2. 配置文件 (application.yml)
radius:
  server:
    auth-port: 1812          # RADIUS认证端口(默认1812)
    acct-port: 1813          # RADIUS计费端口(默认1813)
    secret: ${RADIUS_SECRET:ruoyi123}  # 共享密钥(需与NAS设备配置一致)
  datasource:
    nas-table: sys_nas       # 存储NAS设备信息的数据库表
    user-radius-table: sys_user_radius  # 用户扩展属性表(可选)
3. 核心类与实现原理
(1) RadiusServerConfig (配置类)
@Configuration
public class RadiusServerConfig {
    @Value("${radius.server.auth-port}") 
    private int authPort;  // 从配置注入认证端口

    @Value("${radius.server.secret}")
    private String secret; // 共享密钥

    @Bean
    public RadiusServer radiusServer() {
        return new RadiusServer(authPort, secret); // 初始化RADIUS服务实例
    }
}

功能:初始化 RADIUS 服务器实例,绑定端口与共享密钥。
关键变量

  • authPort:监听认证请求的端口(1812)。
  • secret:加密通信的共享密钥,需与 NAS 设备配置一致。
(2) RuoyiRadiusHandler (请求处理器)
public class RuoyiRadiusHandler implements PacketHandler {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public RadiusPacket handlePacket(RadiusPacket request) {
        // 1. 提取用户名密码
        String username = request.getAttribute("User-Name").getValueString();
        String password = request.getAttribute("User-Password").getValueString();

        // 2. 调用Spring Security认证
        UsernamePasswordAuthenticationToken token = 
            new UsernamePasswordAuthenticationToken(username, password);
        Authentication auth = authenticationManager.authenticate(token);

        // 3. 构建响应包
        RadiusPacket response = new RadiusPacket(RadiusPacket.ACCESS_ACCEPT);
        response.addAttribute("Reply-Message", "Welcome!");

        // 4. 添加动态授权属性(如VLAN)
        CustomAttributeFactory.addAttributes(response, auth.getAuthorities());
        return response;
    }
}

功能:处理 Access-Request 认证请求,集成 Spring Security 完成用户校验,并返回授权属性。
关键方法

  • handlePacket():核心入口,解析请求并调用认证逻辑。
  • addAttributes():根据用户角色动态添加 RADIUS 响应属性。
(3) RadiusUserDetailsService (用户服务)
@Service
public class RadiusUserDetailsService implements UserDetailsService {
    @Autowired
    private SysUserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) {
        SysUser user = userMapper.selectUserByUserName(username);
        if (user == null) throw new UsernameNotFoundException("用户不存在");

        // 构建Spring Security用户对象
        return new org.springframework.security.core.userdetails.User(
            user.getUserName(),
            user.getPassword(),
            AuthorityUtils.createAuthorityList("ROLE_" + user.getRoles())
        );
    }
}

功能:从若依用户表 sys_user 加载用户信息,转换为 Spring Security 可识别的 UserDetails 对象。
关键变量

  • SysUserMapper:若依原生的用户数据访问接口。
(4) NasServiceImpl (NAS设备服务)
@Service
public class NasServiceImpl implements NasService {
    @Autowired
    private NasMapper nasMapper;

    @Override
    public NasDevice validateNas(String ip, String secret) {
        NasDevice nas = nasMapper.selectByIpAndSecret(ip, secret);
        if (nas == null || nas.getStatus() != 0) {
            throw new RadiusException("NAS设备未注册或已禁用");
        }
        return nas;
    }
}

功能:校验请求来源的 NAS 设备是否合法(IP 和密钥是否匹配数据库记录)。
关键SQLselectByIpAndSecret 查询 sys_nas 表验证设备。


三、测试验证全流程
1. 环境准备
  1. 启动若依后台
    cd ruoyi-admin && mvn spring-boot:run  # 确保用户数据已初始化
    
  2. 启动Ruoyi-Radius服务
    cd ruoyi-radius && mvn spring-boot:run  # 检查1812/1813端口监听
    
  3. 安装测试工具
    # 安装FreeRADIUS客户端(Linux)
    sudo apt-get install freeradius-utils
    
2. 添加测试数据
  1. 若依后台添加用户
    • 路径:系统管理 -> 用户管理,创建用户 testuser,状态设为“正常”。
  2. 数据库插入NAS设备
    INSERT INTO sys_nas (nas_name, ip_address, secret, status) 
    VALUES ('Test-Device', '127.0.0.1', 'ruoyi123', 0);
    
3. 认证测试(Authentication)
radtest -t pap testuser password123 127.0.0.1 1812 0 ruoyi123

请求参数

  • -t pap:使用 PAP 认证协议。
  • 0:NAS 端口号(通常为0)。
  • ruoyi123:与 sys_nas.secret 一致的共享密钥。

成功响应

Received Access-Accept ID 15
  Reply-Message = "Authentication Success"
  Tunnel-Type:VLAN = 13
  Tunnel-Medium-Type:IEEE-802 = 6
  Tunnel-Private-Group-Id:VLAN = "100"

日志验证

DEBUG c.r.r.handler.RuoyiRadiusHandler - 用户 testuser 认证通过
DEBUG c.r.r.attr.CustomAttributeFactory - 分配VLAN 100 至用户 testuser
4. 授权测试(Authorization)

验证动态属性返回

  • 检查响应包中的 Tunnel-Private-Group-Id 是否与用户角色关联的 VLAN 一致。
  • 若需自定义属性(如带宽),需在 sys_user_radius 表添加字段,并在 CustomAttributeFactory 中实现逻辑。
5. 计费测试(Accounting)
# 模拟计费请求(需实现AccountingHandler)
raclient -f /path/to/acct-request.txt 127.0.0.1 1813 ruoyi123

请求文件示例 (acct-request.txt)

Acct-Status-Type = Start
User-Name = "testuser"
Acct-Session-Id = "123456"
Framed-IP-Address = 192.168.1.100

计费处理逻辑

  • 服务端需实现 AccountingHandler 记录会话开始/结束时间、流量统计到数据库。
6. 结果验证
  • 数据库检查:查看 sys_radius_accounting 表中是否生成计费记录。
  • 日志分析
    INFO  c.r.r.handler.AccountingHandler - 用户 testuser 会话开始,ID: 123456
    

四、常见错误排查
错误现象可能原因解决方案
NAS not foundNAS设备IP或密钥未配置检查 sys_nas 表数据
User is disabled用户状态为“停用”在若依后台启用用户
Invalid shared secretNAS密钥与服务器配置不一致同步 sys_nas.secret 与配置文件
No response from server端口未开放或服务未启动检查防火墙规则,确认服务监听端口

五、扩展场景实现
1. 动态带宽控制
  1. 数据库扩展
    ALTER TABLE sys_user_radius ADD COLUMN bandwidth_limit VARCHAR(20);
    
  2. 修改属性工厂类
    public class CustomAttributeFactory {
        public static void addAttributes(RadiusPacket response, UserDetails user) {
            // 查询用户带宽限制
            String limit = userRadiusMapper.selectBandwidth(user.getUsername());
            response.addAttribute("Mikrotik-Rate-Limit", limit); // 示例:Mikrotik设备属性
        }
    }
    
2. 多因素认证(MFA)
  1. 集成短信/OTP
    public class RuoyiRadiusHandler {
        public RadiusPacket handlePacket(RadiusPacket request) {
            // 认证通过后检查是否需二次验证
            if (mfaService.isMfaRequired(user)) {
                response.addAttribute("Reply-Message", "请输入短信验证码");
                response.setCode(RadiusPacket.ACCESS_CHALLENGE); // 返回挑战请求
            }
        }
    }
    

六、注意事项
  1. 密钥安全:共享密钥(radius.server.secret)需加密存储,禁止明文暴露。
  2. NAS设备管理:定期审计 sys_nas 表,禁用未授权的设备。
  3. 用户状态同步:若依后台禁用用户后,需实时生效(可结合Redis缓存失效机制)。

通过以上实现,Ruoyi-Radius 模块可为企业级网络提供完整的 AAA 服务,并支持灵活的策略扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值