基于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配置要点
- 启用rlm_python模块:在
radiusd.conf中添加或修改如下配置:
python { module = /path/to/your/crowd_radius.py # 替换为你的脚本路径 }
- 调整站点配置:在
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
相关产品推荐
相关产品推荐

