You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Atlassian Crowd的FreeRADIUS用户认证实现技术问询

我之前刚好做过FreeRADIUS和Atlassian Crowd的集成,踩过一些坑,给你分享一个完整的实现方案,完全满足你要的基于RESTful后端、无需在authorize环节接触密码的需求。

核心思路说明

FreeRADIUS的认证流程里,authorize环节主要负责确认用户身份合法性(比如用户是否存在、是否有认证权限),而authenticate环节才是真正做密码验证的步骤。我们可以利用这个分工,把Crowd的用户存在性检查放在authorize,密码验证放在authenticate,全程通过Crowd的REST API完成,完全不需要在脚本中处理明文密码。

rlm_python脚本实现示例

下面是完整的Python脚本,依赖requests库来调用Crowd API,你需要先在FreeRADIUS服务器上安装pip install requests:

import requests
import radiusd

# 配置Crowd实例信息和服务账号
CROWD_BASE_URL = "https://your-crowd-domain.com/crowd"
CROWD_SERVICE_USER = "freeradius-integration"  # 给FreeRADIUS创建的Crowd服务账号
CROWD_SERVICE_PASS = "your-service-account-password"  # 服务账号的密码

def authorize(p):
    # 从Radius请求中提取用户名
    username = p.get('User-Name', [None])[0]
    if not username:
        radiusd.radlog(radiusd.L_ERR, "No username provided in request")
        return radiusd.RLM_MODULE_REJECT

    # 调用Crowd API检查用户是否存在
    try:
        user_check_url = f"{CROWD_BASE_URL}/rest/usermanagement/1/user?username={username}"
        response = requests.get(
            user_check_url,
            auth=(CROWD_SERVICE_USER, CROWD_SERVICE_PASS),
            timeout=5
        )
        response.raise_for_status()
    except requests.exceptions.RequestException as e:
        radiusd.radlog(radiusd.L_ERR, f"Crowd API error during user lookup: {str(e)}")
        return radiusd.RLM_MODULE_REJECT

    # 用户存在,标记使用Python模块完成后续认证
    p['Auth-Type'] = 'Python'
    return radiusd.RLM_MODULE_OK

def authenticate(p):
    # 提取用户名和用户提交的密码
    username = p.get('User-Name', [None])[0]
    user_password = p.get('User-Password', [None])[0]
    
    if not username or not user_password:
        radiusd.radlog(radiusd.L_ERR, "Missing username or password in auth request")
        return radiusd.RLM_MODULE_REJECT

    # 调用Crowd的密码验证API
    try:
        auth_url = f"{CROWD_BASE_URL}/rest/usermanagement/1/user/authentication?username={username}"
        # Crowd的密码验证API要求将明文密码放在请求体中
        response = requests.post(
            auth_url,
            data=user_password,
            auth=(CROWD_SERVICE_USER, CROWD_SERVICE_PASS),
            timeout=5
        )
        response.raise_for_status()
    except requests.exceptions.HTTPError as e:
        # 401状态码明确表示密码验证失败
        if response.status_code == 401:
            radiusd.radlog(radiusd.L_ERR, f"Password validation failed for user {username}")
        else:
            radiusd.radlog(radiusd.L_ERR, f"Crowd API error during auth: {str(e)}")
        return radiusd.RLM_MODULE_REJECT
    except requests.exceptions.RequestException as e:
        radiusd.radlog(radiusd.L_ERR, f"Network error connecting to Crowd: {str(e)}")
        return radiusd.RLM_MODULE_REJECT

    # 密码验证通过
    return radiusd.RLM_MODULE_OK
FreeRADIUS配置要点
  1. 启用rlm_python模块:在radiusd.conf中添加或修改如下配置:
python {
    module = /path/to/your/crowd_radius.py  # 替换为你的脚本路径
}
  1. 调整站点配置:在sites-available/default(或你使用的站点配置文件)中,将python模块加入authorize和authenticate块:
authorize {
    # 保留原有的其他模块(比如preprocess、chap等)
    python
}

authenticate {
    # 确保这里只有python模块,或者将其放在合适的位置
    python
}
关键注意事项
  • 给Crowd的服务账号分配必要的最小权限:只需要“查看用户”和“验证用户密码”的权限即可,避免过度授权。
  • 处理API超时和异常:脚本中已经加入了超时处理,你可以根据实际情况调整超时时间。
  • 可选优化:可以加入简单的缓存机制(比如用字典缓存最近验证过的用户),减少重复的Crowd API调用,提升认证性能。
  • 测试:先在Crowd中创建一个测试用户,用radtest命令测试认证流程:radtest testuser testpassword your-radius-server 0 testing123

内容的提问来源于stack exchange,提问作者Cameron Lowell Palmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:11:42