H3C SecPath ACG 1000系列 上网行为管理对接飞书 OAuth2.0 企业认证全流程落地实践
本文基于企业生产真实部署案例,完整记录 H3C SecPath ACG 1000系列 上网行为管理设备通过搭建中间件服务器(172.20.10.1)对接飞书开放平台 OAuth2.0,实现员工飞书扫码一键认证上网的全流程。包含真实配置、生产级代码、交互时序、字段解析、故障排查、生产优化,可直接用于技术分享与现场落地。
前言
企业内网无线认证需替代传统账号密码模式,实现飞书身份一键认证。由于 H3C 设备与飞书开放平台存在接口格式、JSON 结构、参数规范不兼容问题,无法直连对接。本文采用 轻量化异步中间件(FastAPI+httpx) 做协议适配与字段转换,最终实现稳定、高效、可追溯的企业级无线认证方案。
一、核心背景与约束
1. 业务需求
- 终端用户连接企业网→ 触发 H3C Oauth 认证 → 中间件服务器(我的是Windows,可以是Linux) → 飞书扫码授权 → 自动上网
- 认证日志本地化、高并发兼容、内存稳定、无控制台乱码
2. 核心技术约束
- H3C 上网行为管理:仅支持 OAuth2.0 授权码模式,要求扁平 JSON返回(
usercode/username/userorg),仅识别顶层字段 - 飞书开放平台:固定返回嵌套 JSON,接口参数、权限、Token 传递有严格规范
- 网络环境:异步中间件服务器固定 IP
172.20.10.1,H3C 设备网桥 IP172.20.0.2(注意看下图,不是带外管理地址)

3. 方案选型
- ❌ 直连方案:H3C ↔ 飞书(格式不兼容,无法解析用户名)

- ✅ 中间件方案:H3C ↔ 异步中间件 ↔ 飞书(协议转换、字段扁平化、稳定性加固)

二、整体架构
1. 核心组件
- H3C 上网行为管理:OAuth2.0 客户端,认证入口与策略控制
- 异步中间件 (172.20.10.1):基于 FastAPI+httpx 开发的中转服务,承担 H3C 与飞书的协议翻译、字段转换、缓存、日志全功能
- 飞书开放平台:企业身份源,提供 OAuth2.0 授权、用户信息查询
2. 部署信息
- 异步中间件服务器:
172.20.10.1:8000 - H3C 设备回调地址:
http://172.20.0.2:8000/ - 飞书应用:企业自建应用
三、OAuth2.0 全交互流程图

四、全平台核心配置(真实配置)
1. H3C 上网行为管理 OAuth 配置
注意1:172.20.0.2是我的上网行为带内地址,你要改成你的,只改ip不该后缀。(脚本写死)
注意2:172.20.10.1是我的Windows服务器地址,你也要改成你的,只改ip不该后缀。(脚本写死)

| 配置项 | 填写参数 |
|---|---|
| 服务器名称 | 飞书认证 |
| 描述 | H3C 上网行为管理 - 飞书 OAuth 认证 |
| 回调地址 | http://172.20.0.2:8000/ |
| appID | cli_a95XXXXXXXX |
| appSecret | eaQ8UXXXXXXXX |
| 重定向 URL | http://172.20.10.1:8000/oauth/authorize |
| accessToken 获取地址 | http://172.20.10.1:8000/oauth/token |
| accessToken 请求类型 | POST |
| 获取用户信息请求地址 | http://172.20.10.1:8000/oauth/userinfo |
| 获取用户信息请求类型 | POST |
| 获取用户信息所需参数 | client_id=cli_a95XXXXXXXX |
| 授权范围 | userinfo |
| 获取方式 | URL 参数 |
| 获取用户关键字 | username |
2. 飞书开放平台配置
- 授权地址:
https://open.feishu.cn/open-apis/authen/v1/index - Token 接口:
https://open.feishu.cn/open-apis/authen/v1/access_token - 用户信息接口:
https://open.feishu.cn/open-apis/authen/v1/user_info - 重定向 URL:
http://172.20.10.1:8000/callback

- 必开权限:
contact:user.base:readonly(用户基础信息只读)

3. 异步中间件核心配置
- 飞书 AppID / AppSecret:生产真实凭证(请修改python中的对应字段)
- 回调地址:
http://172.20.10.1:8000/callback(请修改python中你的服务器地址) - Token 过期:60 秒
- 缓存上限:2000 条(防内存溢出)
- 日志路径:
D:\login_log.txt
五、生产级异步中间件完整代码(Python)
from fastapi import FastAPI, Request, Cookie, Form, HTTPException
from fastapi.responses import RedirectResponse
import httpx
import uuid
import datetime
from cachetools import TTLCache
import asyncio
import urllib3
# 关闭SSL证书警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
app = FastAPI(title="H3C飞书认证服务")
# ====================== 核心配置(172.20.10.1需要改成你的服务器地址) ======================
FEISHU_APP_ID = "cli_a95XXXXXXX"
FEISHU_APP_SECRET = "eaQ8UXXXXXXX"
CALLBACK_URL = "http://172.20.10.1:8000/callback"
TOKEN_EXPIRE_SECONDS = 60
LOG_FILE = r"D:\login_log.txt"
# ====================== 内存缓存(自动过期、防溢出) ======================
user_cache = TTLCache(maxsize=2000, ttl=TOKEN_EXPIRE_SECONDS)
cache_lock = asyncio.Lock()
# ====================== 日志模块(成功/失败分离) ======================
def write_success_log(name, user_id, mobile, ip):
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log = f"[{now}] 姓名={name} | 用户ID={user_id} | 手机号={mobile} | IP地址={ip}\n"
try:
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(log)
except Exception:
pass
def write_error_log(msg):
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log = f"[{now}] ERROR {msg}\n"
try:
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(log)
except Exception:
pass
# ====================== 异步HTTP客户端 ======================
client = httpx.AsyncClient(timeout=5, verify=False)
# ====================== 飞书接口重试机制(3次重试,抗网络波动) ======================
async def feishu_request(method, url, **kwargs):
for i in range(3):
try:
resp = await client.request(method, url, **kwargs)
resp.raise_for_status()
return resp.json()
except Exception as e:
if i == 2:
write_error_log(f"飞书接口请求失败: {str(e)}")
raise
await asyncio.sleep(0.5 * (i + 1))
# ====================== 核心业务接口 ======================
# 1. H3C授权入口:重定向飞书授权页
@app.get("/oauth/authorize")
async def authorize(request: Request, redirect_uri: str = ""):
url = (
"https://open.feishu.cn/open-apis/authen/v1/index?"
f"app_id={FEISHU_APP_ID}"
f"&redirect_uri={CALLBACK_URL}"
f"&response_type=code"
)
response = RedirectResponse(url)
# 存储H3C回调地址
response.set_cookie("h3c_redirect", redirect_uri, max_age=120)
return response
# 2. 飞书授权回调:处理code、获取用户信息
@app.get("/callback")
async def callback(code: str, request: Request, h3c_redirect: str = Cookie(None)):
try:
# 授权码兑换Access Token
token_data = await feishu_request(
"POST",
"https://open.feishu.cn/open-apis/authen/v1/access_token",
json={
"app_id": FEISHU_APP_ID,
"app_secret": FEISHU_APP_SECRET,
"code": code,
"grant_type": "authorization_code"
}
)
access_token = token_data["data"]["access_token"]
# 获取飞书用户信息
user_data = await feishu_request(
"GET",
"https://open.feishu.cn/open-apis/authen/v1/user_info",
headers={"Authorization": f"Bearer {access_token}"}
)
data = user_data["data"]
# 提取用户字段
username = data.get("name", "")
user_id = data.get("user_id", "")
mobile = data.get("mobile", "")
client_ip = request.client.host
# 记录成功日志
write_success_log(username, user_id, mobile, client_ip)
# 生成自定义Token
user_token = f"USER_{user_id}_{uuid.uuid4().hex[:8]}"
# 存入缓存
async with cache_lock:
user_cache[user_token] = {
"usercode": user_id,
"username": username,
"userorg": ""
}
# 回调H3C设备
if h3c_redirect:
return RedirectResponse(f"{h3c_redirect}&code={user_token}&state=STATE")
return {"code": user_token}
except Exception as e:
write_error_log(f"认证失败: {str(e)}")
raise HTTPException(status_code=500, detail="认证失败")
# 3. H3C获取Token接口
@app.post("/oauth/token")
async def token(code: str = Form(None)):
return {
"access_token": code,
"token_type": "bearer",
"expires_in": TOKEN_EXPIRE_SECONDS
}
# 4. H3C获取用户信息接口(扁平JSON,适配H3C)
@app.post("/oauth/userinfo")
async def userinfo(access_token: str = Form(None)):
try:
async with cache_lock:
return user_cache.get(access_token, {
"usercode": "",
"username": "",
"userorg": ""
})
except Exception as e:
write_error_log(f"userinfo异常: {str(e)}")
return {
"usercode": "",
"username": "",
"userorg": ""
}
# ====================== 服务启动(生产优化) ======================
if __name__ == "__main__":
import uvicorn
# 关闭彩色日志,避免Windows乱码
log_config = uvicorn.config.LOGGING_CONFIG
log_config["formatters"]["default"]["use_colors"] = False
log_config["formatters"]["access"]["use_colors"] = False
print("==================================================")
print("H3C飞书认证服务启动成功(日志定制版)")
print("服务地址:http://0.0.0.0:8000")
print(f"日志文件:{LOG_FILE}")
print("==================================================")
uvicorn.run(
app,
host="0.0.0.0",
port=8000,
log_config=log_config,
log_level="warning"
)
六、核心字段映射与交互解析
1. 飞书 → 异步中间件 字段转换
| 飞书嵌套字段 | 中间件扁平字段 | 用途 |
|---|---|---|
| data.name | username | H3C 展示用户名 |
| data.user_id | usercode | 用户唯一标识 |
| 官方 Access Token | 自定义临时 Token | 会话凭证 |
2. 关键接口解析
/oauth/authorize:接收 H3C 授权请求,重定向飞书扫码页/callback:飞书授权回调,处理 code、获取用户信息、格式化数据/oauth/token:返回 H3C 要求的标准 OAuth2.0 Token/oauth/userinfo:返回 H3C 兼容的扁平 JSON 用户信息
七、生产常见故障与解决方案
1. 报错:网页解析失败,可能是不支持的网页类型
- 根因:H3C 仅识别纯 JSON 响应,不兼容 HTML / 文本 / 错误状态码
- 方案:中间件严格返回 JSON,无多余输出,状态码 200
2. 报错:飞书提示「请求非法」
- 根因:飞书重定向 URL 与中间件
CALLBACK_URL不一致 - 方案:飞书后台配置
http://172.20.10.1:8000/callback
3. 间歇性认证失败
- 根因:服务器 DNS 解析不稳定、网络波动
- 方案:中间件代码加入 3 次重试机制
八、生产环境优化要点
- 异步非阻塞架构:FastAPI+httpx 异步处理,单机支撑大量并发认证
- 内存安全:TTLCache 限制缓存条数 + 自动过期,内存占用低且稳定
- 日志优化:成功 / 失败日志分离,本地化存储,无控制台乱码
- 稳定性:飞书接口 3 次重试,抵御网络波动
- 兼容性:Windows / Linux 全平台运行,无环境依赖
九、总结
H3C 上网行为管理与飞书 OAuth2.0 无法直接直连,核心瓶颈为飞书嵌套 JSON与H3C 扁平 JSON的格式冲突、接口参数规范不兼容。
轻量化异步中间件是生产级可行方案,作为唯一中转服务承担协议适配、字段转换、缓存管理、日志追溯全功能,完美实现企业员工飞书扫码一键认证上网,方案已通过长时间、高并发生产验证,稳定可靠、易部署、易维护。
附录:依赖安装命令
pip install fastapi uvicorn httpx cachetools
记得:
Windows服务器放行8000端口,用管理员身份打开 PowerShell,复制运行这一条命令:
New-NetFirewallRule -DisplayName "PythonAuthServer-8000" -Direction Inbound -Protocol TCP -LocalPort 8000 -Action Allow
Linux服务器放行8000端口
Ubuntu
sudo ufw allow 8000/tcp
CentOS
sudo firewall-cmd --permanent --add-port=8000/tcp
PS:20260416 该代码可行,如果飞书换了接口,可以把我的脚本扔给AI,让它帮你改,这里有特殊处理转化,不多做解释。
日常操作指南
1 验证服务是否运行
- 方式1:浏览器访问 http://172.20.10.1:8000,能看到这个页面代表运行正常

- 方式2:打开任务管理器→详细信息,找到 exe 进程即运行正常
- 方式3:飞书扫码认证,查看 D:\login_log.txt 是否新增日志
2 查看登录日志
日志路径:D:\login_log.txt(UTF-8编码,可直接用记事本打开)
日志内容:登录时间、姓名、用户ID、手机号、原始飞书JSON数据(追加写入,不覆盖)
3 手动启动/停止服务
- 手动启动:CMD 进入 D 盘,执行双击py(前台运行,关闭CMD即停止)
- 手动停止:任务管理器→详细信息→找到 exe→结束任务
4 重启服务
- 任务管理器结束exe 进程
- CMD 执行 python D:\feishuOauth.py,或服务器重启后自动启动
常见问题排查
5.1 服务无法访问(浏览器打不开 http://172.20.10.1:8000)
- 服务器检查 python 进程是否运行,未运行则手动启动
5.2 开机自启失败(重启服务器后服务未运行)
- 排查1:检查任务计划程序中,任务是否勾选“使用最高权限运行”“不管用户是否登录都要运行”
- 排查2:检查任务计划的“操作”中,参数和起始于路径是否正确(参数:D:\feishuOauth.py,起始于:D:\)
- 排查3:重新创建任务计划(百度一下python脚本开机自动运行的方法,可以开机自动运行)。

浙公网安备 33010602011771号