Signon 模块 API¶
Signon 模块是 MyApps 平台的**认证与单点登录服务**(obpm-signon),提供账号密码登录、SSO(CAS / OIDC)登录、微信/钉钉扫码登录、短信验证码登录与注册、代理用户登录、自动登录、企业域列表查询、accessToken 换取与刷新、用户注销等认证域能力。该模块默认运行在 8085 端口,context-path 占位符为 ${myapps.context-path.signon:}(部署时替换为具体上下文路径,缺省为空;lite 统一打包下为 /,此时模块路径前缀多一层 /signon)。
注:本模块控制器**不共享统一的
/api/rest前缀**。类级@RequestMapping仅绑定 context-path 占位符,方法级路径各自独立(/conn_test、/、/api/login/...、/api/runtime/login/...、/api/domains、/api/refreshAccessToken、/api/logout.action、/api/open-app、logout/sso)。顶层 index.md「服务与基址」表中 signon 行所列/api/rest仅为占位,实际基址以本文档与各控制器文档为准。覆盖进度:3 / 3 控制器(已覆盖 LoginController、JumpToController、LogoutController)
Signon 模块共有 3 个有端点的控制器,合计 27 个端点(登录 25 + 跳转 1 + 注销 1)。源码树中另有 ContextPathController(/runtime/consul/contextpath,仅用于服务发现查询 runtime 的 contextPath,归入运维/服务发现范畴,不在本认证域文档范围内)不单独成文。
已文档化控制器¶
| 文件 | 中文名 | 基址 | 端点数 |
|---|---|---|---|
login.md |
LoginController(登录控制器) | ${myapps.context-path.signon:} |
25 |
jump-to.md |
JumpToController(跳转控制器) | ${myapps.context-path.signon:} |
1 |
logout.md |
LogoutController(注销控制器) | ${myapps.context-path.signon:} |
1 |
鉴权说明¶
(据源码)Signon 是**认证服务本身**,其设计前提是「在用户取得令牌之前为其服务」,因此**模块内不存在任何强制校验 accessToken/adminToken 的过滤器或拦截器**——这与 runtime(RestSecurityHandlerInterceptor)、message(MessageSecurityFilter)、manager(ManagerSecurityFilter)有本质区别。具体过滤链如下。
启动器与组件扫描¶
启动类 cn.myapps.run.Signon2App(consul / eureka / nacos 三个 profile 与 war 打包同名启动器):
cn.myapps.*.conf 覆盖 cn.myapps.common.conf.CommWebMvcConfig(obpm-common),由此注册共享过滤器;cn.myapps 覆盖 cn.myapps.signon.conf.SignonMvcConfig,注册 CAS 相关过滤器。
过滤器链(按 order 排列)¶
| order | 过滤器 | 来源 | 作用 |
|---|---|---|---|
| HIGHEST_PRECEDENCE | PassFilter(匿名内联 Filter) |
obpm-common CommWebMvcConfig.filterRegistrationBeanPassFilter1 |
命中白名单 URL 即标记 request.setAttribute("pass", true) 并放行,不参与鉴权 |
| -1 | CommonSecurityFilter |
obpm-common CommWebMvcConfig.filterRegistrationBeanCommonSecurityFilter1(URL 模式 /*) |
系统间调用鉴权与 HTTP 方法收敛 |
| 1 | HiddenHttpMethodFilter |
obpm-common CommWebMvcConfig |
允许 POST 表单隐藏 PUT/DELETE |
| 2 | OBPMAuthenticationFilter(CAS) |
signon SignonMvcConfig.casAuthenticationFilter |
**仅当 authentication.type=sso 且 sso.implementation 含 CasUserSSO 时**重定向到 CAS 登录页;其余情况直接放行 |
| 3 | OBPMCas20ProxyReceivingTicketValidationFilter(CAS) |
signon SignonMvcConfig.casTicketValidationFilter |
CAS 票据校验,仅 SSO+CAS 模式下生效 |
signon 不使用 Spring Security(全模块无
org.springframework.security引用),不注册任何 HandlerInterceptor。
CommonSecurityFilter 行为(据 cn.myapps.common.web.CommonSecurityFilter)¶
- 系统间调用放行:携带合法
systemToken请求头(Security.verifySystemToken,JWT 内username固定为systemToken)→ 标记pass=true放行。 - HTTP 方法收敛:仅允许
GET/POST/HEAD/OPTIONS,其他方法返回 HTTP405(HTML 错误页)。OPTIONS为浏览器 CORS 预检放行。 - 系统未就绪:
Environment.isReady()为 false 时返回 HTTP500,响应体「系统正在启动中,请稍后再试!」。 - 文档/监控页保护:
/v3/api-docs、/swagger-ui、/druid须持有效 designerToken 或 adminToken;/actuator/health放开;其余/actuator/**返回401(无响应体)。 - 其他请求:直接
chain.doFilter,不校验业务 token。
PassFilter 白名单(与 signon 相关条目)¶
由 CommWebMvcConfig.filterRegistrationBeanPassFilter1 硬编码(无配置入口),命中即 pass=true:
- 模块首页:
/、/signon、/manager、/manager/、/designer、/designer/ - 登录页面:
/signon/*、/api/runtime/login/*、/api/authtime/login/*、/api/designtime/login/*(lite 下另有/manager/api/authtime/login/*、/designer/api/designtime/login/*、/obpm/api/runtime/login/*) - 调试/移动端登录:
/api/debuglogin/*、/api/login/*、/runtime/app/security/*、/obpm/runtime/app/security/* - 注销:
/api/runtime/logout、/runtime/logout、/api/authtime/logout、/api/designtime/logout等 - runtime 取 token:
/api/rest/accessToken、/rest/accessToken、/api/runtime/secrets/* - 健康检查:
/health、/actuator/health、/kms/health、/ai/health - 静态资源后缀:
.jpg .js .css .ico .png .gif .html .json .map .woff2 .woff .ttf .eot .svg .mpg .mp4 .mp3 .wav .avi .flv .m3u8 .m3 .ts - magic-api:
/magic-api/*、/obpm/magic-api/*
signon 大部分端点位于
/api/runtime/login/**,全部落在白名单内;/api/login/exchangeAccessToken、/api/domains、/api/refreshAccessToken、/api/logout.action、/api/open-app、/conn_test、/、logout/sso不在白名单,但因CommonSecurityFilter不做 token 校验,仍可匿名访问。
CAS 单点登录(可选)¶
当部署方配置 authentication.type=sso 且 sso.implementation 含 CasUserSSO 时,OBPMAuthenticationFilter 会对未持有 CAS 断言(session 内 CONST_CAS_ASSERTION)的请求重定向到 CAS 登录页;其中 /actuator/health 与匹配 logout.action 的 URI 直接放行,微信浏览器(User-Agent 含 MicroMessenger)也直接放行。OIDC(OidcSSO)与微信/钉钉扫码登录走控制器内的 LoginController 逻辑,不经 CAS 过滤器。
执行用户¶
signon 控制器**不通过过滤器注入执行用户**。需要识别用户的端点在控制器内自行解析:
- Cookie
checkInToken:signIn、getUserDomains从该 cookie 取中间令牌(Security.getUserIdFromToken,60 秒有效期,由checkin端点签发),缺失返回「登录已失效,请重新登录」。 - Cookie 自动登录票据:
autologin通过CookieAuthValidator.valid(request, response)校验。 - 请求内 accessToken:
refreshAccessToken调用Security.getUserIdFromToken(request),按 query 参数accessToken→ queryaccess_token→ 请求头accessToken→ CookieaccessToken→Authorization: Bearer <token>顺序解析。 - 路径变量 / 业务参数:
getProxyUsers、loginProxy、exchangeAccessToken等以业务参数(用户 id、域名)定位用户,不依赖请求级鉴权。
完整鉴权机制与错误码说明见:顶层 index.md。
响应结构与错误码¶
Signon 模块控制器返回**多种响应形态**(按控制器 / 方法区分),不全部采用顶层统一 Resource:
形态一:Resource(统一响应)¶
仅 LogoutController 使用。由 new Resource(0, errmsg, data, null) 构造,与顶层 index.md「统一响应结构」一致:
形态二:result(...) 自定义包装(LoginController 多数端点)¶
由 LoginController.result(resultCode, msg, dataName, data, ...) 构造,序列化为 JSON:
{
"resultCode": "0|1|7|400",
"msg": "<描述>",
"<dataName>": <data>,
["<dataName2>": <data2>],
["<dataName3>": <data3>]
}
| 字段 | 类型 | 说明 |
|---|---|---|
| resultCode | string | 业务码:"1"=成功,"0"=失败/通用错误,"7"=密码已过期,"400"=参数/校验错误 |
| msg | string | 描述信息 |
| 其他键 | 任意 | 动态数据键(如 accessToken、returnUrl、domains、checkcode、checkcodeImg、timeout、url、multiLangWordList、result、proxyUsers),具体见各端点 |
该形态**与顶层统一
Resource不同**——字段名是resultCode/msg而非errcode/errmsg。
形态三:success/error 自定义包装(LoginController getDomains)¶
| 字段 | 类型 | 说明 |
|---|---|---|
| status | int | 0=成功(错误时也为 0,错误信息走 message/data) |
| message | string | "ok" 或 "error" |
| data | object/null | 业务数据 |
形态四:原始 JSON / HTML 字符串¶
- 原始
JSONObject:getWxConfig、getDdConfig、getSessionKey直接返回JSONObject,无外层包装。 - HTML/JS 字符串:
test(/conn_test)、doIndexPage(/)、doSSO、dologoutSSO、wxQrCodeLogin、ddQrCodeLogin通过@ResponseBody返回形如<script>window.location='...'</script>的 HTML,由浏览器执行跳转;登录成功者同时通过Set-Cookie下发accessToken。
错误码补充¶
Signon 模块**未引入模块专属业务错误码**(HTTP 层由 CommonSecurityFilter 统一处理)。鉴权 / 启动层引入以下与统一 Resource 不同的纯 HTTP 状态码:
| errcode / resultCode | HTTP | 含义 |
|---|---|---|
| 405 | 405 | HTTP 方法不被允许(由 CommonSecurityFilter 拦截,仅允许 GET/POST/HEAD/OPTIONS,返回 HTML 错误页) |
| 500 | 500 | 系统正在启动中(CommonSecurityFilter 在 Environment.isReady() 为 false 时返回,HTML 错误页) |
| 401 | 401 | 访问 /actuator/**(除 /actuator/health 外)未授权;/v3/api-docs、/swagger-ui、/druid 未持有效 designerToken/adminToken 时返回提示页 |
resultCode "0" |
200 | 业务失败(账号锁定、密码错误、验证码错误、用户不存在等,包在 result 自定义结构中) |
resultCode "7" |
200 | 密码已过期(包在 result 自定义结构中,附带 code 为重置用临时 token) |
resultCode "400" |
200 | 参数校验错误(如 exchangeAccessToken 未传 domainId/domainName,包在 result 自定义结构中) |
覆盖说明¶
本阶段覆盖 obpm-signon 工作树下的 LoginController(登录控制器,25 个端点,含首页重定向、连接测试、checkin/signin 两步登录、SSO/CAS/OIDC 登录、微信/钉钉扫码登录回调、短信验证码登录与注册、代理用户登录、自动登录、企业域列表、多语言词列表、accessToken 换取与刷新、密码找回)、JumpToController(跳转控制器,1 个端点,写 cookie 后 JS 跳转至门户首页)、LogoutController(注销控制器,1 个端点,注销后返回重定向 URL)。除 ContextPathController(服务发现辅助,非认证域)外,Signon 模块有端点控制器已**全部覆盖**。