登录认证与消息推送扩展
登录认证与消息推送是两类最常见的二次开发任务,核心代码集中在三个文件:
myapp/project.py:用户自定义模块。包含推送函数(push_admin/push_message等)和认证中转网关MyCustomRemoteUserView。myapp/views/view_login.py:各种登录方式(DB / LDAP / OAuth2 / CAS / 飞书 / 企业微信 / 钉钉 / 微信)的具体实现。myapp/security.py:安全管理器MyappSecurityManager,负责用户注册、角色权限以及视图注册。
说明:本仓库当前的认证体系与早期 Flask-AppBuilder「单一 AUTH_TYPE」模式不同,请以本页描述为准。
一、登录认证
1. 总体架构
平台统一固定 AUTH_TYPE = AUTH_REMOTE_USER,由代码强制设置,config.py 中无需配置(见 myapp/security.py:642)。所有未登录请求先进入认证中转网关 MyCustomRemoteUserView(注册为 /login/ 路由),再由它的 login() 决定跳转到哪一种具体登录方式。
具体的登录方式各自在 myapp/views/view_login.py 中注册独立路由:
| 登录方式 | 路由前缀 | 视图类 | 说明 |
|---|---|---|---|
| 账号密码 / LDAP | /login/db/ |
Myauthdbview |
数据库账号密码,密码不匹配时尝试 LDAP bind 兜底 |
| OAuth2 / OIDC | /login/oauth2/ |
OAuth2LoginView |
支持 GitHub / Google 预设,或自定义 IdP(Keycloak、Okta、Azure AD 等) |
| CAS 单点登录 | /login/cas/ |
CASLoginView |
|
| 飞书 | /login/feishu/ |
FeishuLoginView |
|
| 企业微信 | /login/wecom/ |
WeComLoginView |
|
| 钉钉 | /login/dingtalk/ |
DingTalkLoginView |
|
| 微信开放平台 | /login/wechat/ |
WeChatLoginView |
需在 open.weixin.qq.com 创建"网站应用"并通过审核 |
注意:
Myauthdbview类位于myapp/views/view_login.py(route_base =/login/db),不在project.py中。project.py中只有中转网关MyCustomRemoteUserView。
默认账号密码为 admin/admin。
2. 选择登录方式 / 对接 SSO
修改 myapp/project.py 中 MyCustomRemoteUserView.login() 的 redirect:
- 默认:
return redirect('/frontend/login'),跳到前端 DB 登录页(最终调用后端/login/db/)。 - 切换到内置 SSO,改为对应路由即可,例如:
return redirect('/login/oauth2/') # OAuth2 / GitHub / Google return redirect('/login/cas/') # CAS return redirect('/login/feishu/') # 飞书 return redirect('/login/wecom/') # 企业微信 return redirect('/login/dingtalk/') # 钉钉 return redirect('/login/wechat/') # 微信 - 对接自定义三方 SSO:在
login()内重定向到三方授权页,回调带code回到/login/后,用code换取用户名,再调用myapp/views/view_login.py中的通用函数_sso_login_or_register(appbuilder, username=...)完成查找 / 自动注册 / 登录。project.py顶部注释里给出了完整示例代码。
注意:
/frontend/login、/frontend/等前端路径与你所在环境的 URL 前缀(/backend、istio 网关放行规则)相关,部署时请确认前端登录页的实际访问地址。
3. 各登录方式的配置项
SSO 相关配置在 myapp/config.py 中(默认全部注释,按需开启),路由跳转到对应 /login/xxx/ 时才生效:
- OAuth2 / OIDC:
OAUTH2_PROVIDER(填github/google可自动补全端点 URL)、OAUTH2_CLIENT_ID、OAUTH2_CLIENT_SECRET、OAUTH2_AUTHORIZE_URL、OAUTH2_TOKEN_URL、OAUTH2_USERINFO_URL、OAUTH2_SCOPES、OAUTH2_USERNAME_FIELD、OAUTH2_EMAIL_FIELD、OAUTH2_REDIRECT_URI、OAUTH2_LOGOUT_URL。 - CAS:
CAS_SERVER_URL、CAS_SERVICE_URL、CAS_LOGOUT_URL。 - 飞书:
FEISHU_APP_ID、FEISHU_APP_SECRET、FEISHU_REDIRECT_URI。 - 企业微信:
WECOM_CORPID、WECOM_AGENTID、WECOM_CORPSECRET、WECOM_REDIRECT_URI。 - 钉钉:
DINGTALK_APP_KEY、DINGTALK_APP_SECRET、DINGTALK_REDIRECT_URI。 - 微信:
WECHAT_APP_ID、WECHAT_APP_SECRET、WECHAT_REDIRECT_URI。 - LDAP(
/login/db/中密码不匹配时兜底):AUTH_LDAP_SERVER、AUTH_LDAP_PORT、AUTH_LDAP_USE_TLS、AUTH_LDAP_BASE_DN。
各 REDIRECT_URI 留空时会自动拼接为 <本应用地址>/login/<方式>/callback。
4. Header / Token 认证(接口调用免登录)
myapp/security.py 的 load_user_from_header 支持通过请求头认证:
- username 直传:当全局开启
AUTH_PLATFORM_ACCESS=True,或通过 K8s 集群内部域名(host 含kubeflow-dashboard.infra)访问时,header 值(长度 < 40)直接当作用户名免认证放行。 - JWT Token:否则按 JWT 解析,密钥为
JWT_PASSWORD(config.py:241中默认myapp;代码读取不到该配置时的兜底值为cube-studio,见myapp/security.py:171,669),算法HS256,sub字段为用户名。对只有payload.signature两段的短 token 会自动补回固定的 HS256 header。
认证 header 头名称由 AUTH_HEADER_NAME 控制,默认 Authorization。
5. 自定义安全管理器
如需更深度定制(用户字段、角色映射等),可在 config.py 设置 CUSTOM_SECURITY_MANAGER,其类必须继承 MyappSecurityManager(见 myapp/__init__.py:298-301)。注册与权限逻辑在 myapp/security.py 中实现。
二、消息推送
推送函数在 myapp/project.py 中,定时调度和异步任务发起通知时会调用它们。用户可自行实现 / 改写:
| 函数 | 签名 | 用途 | 使用的渠道配置 |
|---|---|---|---|
push_admin |
push_admin(message) |
推送给管理员 | PUSH_CONFIG[PUSH_ADMIN_CHANNEL] |
push_message |
push_message(receivers, message, link=None) |
推送给指定用户 | PUSH_CONFIG[PUSH_CHANNEL] |
push_resource_apply |
push_resource_apply(notebook_id, pipeline_id, task_id, service_id, **kwargs) |
资源申请通知(默认空操作,按需实现) | — |
push_resource_approve |
push_resource_approve(notebook_id, pipeline_id, task_id, service_id, **kwargs) |
资源审批通知(默认空操作,按需实现) | — |
push_admin / push_message 默认都委托给 myapp/utils/push.py 的 push_message(push_config, message, receivers=None) 实现实际发送。
推送渠道配置
在 myapp/config.py 中(约 909-942 行):
PUSH_ADMIN_CHANNEL = '' # 管理员消息使用的渠道名,对应 PUSH_CONFIG 的 key
PUSH_CHANNEL = '' # 普通用户消息使用的渠道名
PUSH_CONFIG = {
"channel1": {
"type": 'wecom-bot', # 渠道类型
"webhook-key": "xxxxxxxx" # 群机器人 webhook key
},
"channel2": { ... },
}
ENABEL_ALERT_HOMEPAGE = True # 报警消息是否在首页显示(注意拼写为 ENABEL)
type 支持的渠道类型(见 myapp/utils/push.py):
wecom-bot:企业微信群机器人dingtalk-bot:钉钉群机器人feishu-bot:飞书群机器人email:邮件webhook:通用 webhook
要接入自有 IM / 工单系统,可直接重写 project.py 中的 push_admin / push_message,或在 utils/push.py 的 push_message 中新增渠道分支。
相关
- 接口与认证头速查:见 07-参考速查/核心API速查.md
- 前端访问路径与网关放行:见 01-架构原理/流量代理与网关.md