auth.yaml 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. Captcha:
  2. get:
  3. operationId: fetchCaptcha
  4. summary: 登录图片验证码签发(安全需求4)
  5. description: 环境变量DMS_CAPTCHA_ENABLED(双版同名,1.40起缺省false)开启时返回captchaId与data:image/png;base64图片(132×44、4位字符剔除易混淆0O1I、120秒过期、一次性消费);关闭时仅返回enabled=false。登录页据enabled决定是否展示验证码输入;请求与响应均不缓存。
  6. security: []
  7. parameters:
  8. - $ref: '../components/parameters.yaml#/XRequestId'
  9. responses:
  10. '200':
  11. description: 验证码签发结果
  12. content:
  13. application/json:
  14. schema:
  15. type: object
  16. required: [code, message, data, requestId]
  17. properties:
  18. code: {type: string, enum: [OK]}
  19. message: {type: string, enum: [success]}
  20. requestId: {type: string, format: uuid}
  21. data:
  22. type: object
  23. required: [enabled, passwordLoginDisabled]
  24. additionalProperties: false
  25. properties:
  26. enabled: {type: boolean, description: 验证码开关当前值}
  27. passwordLoginDisabled: {type: boolean, description: 禁用用户名密码登录开关回显(1.39安全管控,仅Java版);true时登录页隐藏账号密码表单,POST /auth/login一律403}
  28. captchaId: {type: string, description: 验证码标识,登录时原样携带;enabled=true时必返}
  29. image: {type: string, description: data:image/png;base64图片,img标签src直接使用;enabled=true时必返}
  30. '500':
  31. $ref: '../components/responses.yaml#/InternalError'
  32. ResetPasswordRequest:
  33. post:
  34. operationId: createResetPasswordRequest
  35. summary: 登录前提交重置密码申请(契约1.49)
  36. description: 登录界面(账号密码与单点登录独立密码界面)自助提交:username接受用户名或姓名(重名歧义按用户不存在处理,与登录口径一致);验证码开启(DMS_CAPTCHA_ENABLED)时请求体须含captchaId/captchaCode(与登录同一验证码,一次性消费)。按申请用户类型路由审批角色——首长(userType=COMMANDER)→DMS_RESET_PASSWORD_APPROVER_ROLE_COMMANDER(缺省「安全管理员」)、其他用户→DMS_RESET_PASSWORD_APPROVER_ROLE_NORMAL(缺省「系统管理员」),向该角色全部活跃挂载用户发PASSWORD_RESET待办通知(至少一人,否则400);内置admin拒绝申请(400);已有待审申请返回409 PASSWORD_RESET_DUPLICATE;用户不存在/停用返回400。审批人在通知页待办处理(AGREE/REJECT,先到先得,二次认证),通过后该用户password_hash/last_login_at置NULL(回首次登录态,门户验签进入SET_PASSWORD阶段重新设置独立密码)、auth_version+1旧会话全部失效;本地账号密码登录对已重置账号返回403「该账号密码已重置,请通过单点登录进入并重新设置密码」。
  37. security: []
  38. parameters:
  39. - $ref: '../components/parameters.yaml#/XRequestId'
  40. requestBody:
  41. required: true
  42. content:
  43. application/json:
  44. schema:
  45. type: object
  46. additionalProperties: false
  47. required: [username]
  48. properties:
  49. username: {type: string, description: 用户名或姓名。}
  50. captchaId: {type: string, description: 验证码标识(验证码开启时必填)。}
  51. captchaCode: {type: string, description: 验证码字符(验证码开启时必填)。}
  52. responses:
  53. '200':
  54. description: 申请已受理
  55. content:
  56. application/json:
  57. schema:
  58. type: object
  59. required: [code, message, data, requestId]
  60. properties:
  61. code: {type: string, enum: [OK]}
  62. message: {type: string, enum: [success]}
  63. requestId: {type: string, format: uuid}
  64. data:
  65. type: object
  66. required: [requestId, notified]
  67. additionalProperties: false
  68. properties:
  69. requestId: {$ref: '#/StringId'}
  70. notified: {type: integer, minimum: 1, description: 收到待办通知的审批人数。}
  71. '400': {$ref: '../components/responses.yaml#/BadRequest'}
  72. '409': {$ref: '../components/responses.yaml#/Conflict'}
  73. '500': {$ref: '../components/responses.yaml#/InternalError'}
  74. Login:
  75. post:
  76. operationId: login
  77. summary: 用户登录
  78. description: 验证码开启(DMS_CAPTCHA_ENABLED,1.40起缺省false)时请求体必须且只能包含五键(追加captchaId/captchaCode),验证码校验先于用户查询与锁定检查、一次性消费不计入登录失败锁定,错误返回400 INVALID_CAPTCHA;关闭时保持三键(username/password/keepSignedIn)。可选键roleId(契约1.46 多角色,数字字符串)与验证码开闭正交(关闭时三或四键、开启时五或六键)——密码/验证码/锁定/IP全过后挂载多个活跃启用角色且未带roleId时返回RoleSelectionData选择步骤(不签发令牌、不记登录成功),前端选定后携带roleId二次提交;roleId不在挂载列表内返回400 INVALID_ARGUMENT。会话锁定单角色:选定roleId写入JWT roleId claim(数字),切换角色需重新登录;单角色自动选中、无挂载走默认角色(claim为null)。密码即角色(契约1.53):先遍历挂载行独立密码哈希,命中即以该角色直接签发进入;未命中回退用户级密码验证,命中且恰一个挂载行未设独立密码时以该角色进入;挂载行全未设独立密码的多角色为存量过渡态,维持上述选择步骤(显式roleId路径保留兼容)。本地重设密(契约1.65):密码被重置审批清空(契约1.49)的用户本地登录不再返回403——验证码/锁定/IP守卫照常通过后,无论输入什么密码都返回SetupPasswordPhaseData设密载荷(与门户验签SET_PASSWORD同构、票据一次性5分钟有效),前端进入与单点登录首次设密同一界面重新设密;审计以reason=PASSWORD_RESET留痕。
  79. security: []
  80. parameters:
  81. - $ref: '../components/parameters.yaml#/XRequestId'
  82. requestBody:
  83. required: true
  84. content:
  85. application/json:
  86. schema:
  87. $ref: '../components/schemas.yaml#/LoginRequest'
  88. responses:
  89. '200':
  90. description: 登录成功(多角色未带roleId返回RoleSelectionData选择步骤;密码被重置审批清空返回SetupPasswordPhaseData设密步骤)
  91. content:
  92. application/json:
  93. schema:
  94. $ref: '../components/schemas.yaml#/LoginResponse'
  95. '400':
  96. description: 请求参数错误或验证码缺失/错误/过期(INVALID_CAPTCHA,安全需求4)
  97. content:
  98. application/json:
  99. schema:
  100. $ref: '../components/schemas.yaml#/ErrorResponse'
  101. '401':
  102. $ref: '../components/responses.yaml#/AuthenticationError'
  103. '403':
  104. $ref: '../components/responses.yaml#/Forbidden'
  105. '500':
  106. $ref: '../components/responses.yaml#/InternalError'
  107. Logout:
  108. post:
  109. operationId: logout
  110. summary: 注销并使当前用户旧Token失效
  111. parameters:
  112. - $ref: '../components/parameters.yaml#/XRequestId'
  113. responses:
  114. '200':
  115. description: 注销成功
  116. content:
  117. application/json:
  118. schema:
  119. $ref: '../components/schemas.yaml#/EmptySuccessResponse'
  120. '400':
  121. $ref: '../components/responses.yaml#/InvalidArgument'
  122. '401':
  123. $ref: '../components/responses.yaml#/AuthenticationError'
  124. '403':
  125. $ref: '../components/responses.yaml#/Forbidden'
  126. '500':
  127. $ref: '../components/responses.yaml#/InternalError'
  128. Reauth:
  129. post:
  130. operationId: reauth
  131. summary: 敏感操作二次认证(重输登录密码换取5分钟reauth令牌)
  132. description: 登录态下重输登录密码,签发type=reauth的短时令牌(绑定sub与authVersion,不可冒充访问令牌);不写审计、不计入登录失败锁定。
  133. parameters:
  134. - $ref: '../components/parameters.yaml#/XRequestId'
  135. requestBody:
  136. required: true
  137. content:
  138. application/json:
  139. schema:
  140. type: object
  141. required: [password]
  142. additionalProperties: false
  143. properties:
  144. password: {type: string, format: password, minLength: 1}
  145. responses:
  146. '200':
  147. description: 二次认证成功
  148. content:
  149. application/json:
  150. schema:
  151. type: object
  152. required: [code, message, data, requestId]
  153. properties:
  154. code: {type: string, enum: [OK]}
  155. message: {type: string, enum: [success]}
  156. requestId: {type: string, format: uuid}
  157. data:
  158. type: object
  159. required: [reauthToken, expiresIn]
  160. properties:
  161. reauthToken: {type: string, description: 二次认证令牌,经X-DMS-Reauth-Token请求头携带}
  162. expiresIn: {type: integer, enum: [300], description: 固定300秒(5分钟)}
  163. '400':
  164. $ref: '../components/responses.yaml#/InvalidArgument'
  165. '401':
  166. $ref: '../components/responses.yaml#/AuthenticationError'
  167. '500':
  168. $ref: '../components/responses.yaml#/InternalError'
  169. PortalVerify:
  170. post:
  171. operationId: verifyPortalLaunch
  172. summary: 统一门户跳转验签
  173. description: 透传浏览器地址栏query串验签,按需落库建档并同步组织信息;返回跳转阶段,首次进入需设置独立密码。
  174. security: []
  175. parameters:
  176. - $ref: '../components/parameters.yaml#/XRequestId'
  177. requestBody:
  178. required: true
  179. content:
  180. application/json:
  181. schema:
  182. type: object
  183. required: [query]
  184. additionalProperties: false
  185. properties:
  186. query: {type: string, minLength: 1, description: 门户跳转链接的完整query串}
  187. responses:
  188. '200':
  189. description: 验签结果
  190. content:
  191. application/json:
  192. schema:
  193. type: object
  194. required: [code, message, data, requestId]
  195. properties:
  196. code: {type: string}
  197. message: {type: string}
  198. requestId: {type: string}
  199. data:
  200. type: object
  201. required: [phase, username, realName]
  202. properties:
  203. phase: {type: string, enum: [LOGIN, SET_PASSWORD], description: SET_PASSWORD时携带一次性设密票据portalTicket及机构选择数据}
  204. username: {type: string}
  205. realName: {type: string}
  206. portalTicket: {type: string}
  207. suggestedOrganizationId: {type: string, nullable: true, description: 按对端机构名/默认组织推断的用户当前机构ID(可能为空),前端预选用}
  208. organizations:
  209. type: array
  210. description: 仅SET_PASSWORD阶段返回;本系统机构树与大系统可能不一致(用户按需同步、机构不自动同步),设密时由用户自选所在机构
  211. items:
  212. type: object
  213. required: [id, orgCode, orgName, orgPath]
  214. additionalProperties: false
  215. properties:
  216. id: {type: string}
  217. orgCode: {type: string}
  218. orgName: {type: string}
  219. orgPath: {type: string}
  220. '400':
  221. $ref: '../components/responses.yaml#/InvalidArgument'
  222. '403':
  223. $ref: '../components/responses.yaml#/Forbidden'
  224. '500':
  225. $ref: '../components/responses.yaml#/InternalError'
  226. PortalProxyVerify:
  227. post:
  228. operationId: verifyProxySso
  229. summary: 本地单点登录代理探测(仅Java版提供)
  230. description: 令牌取自本机单点登录代理(REST直连:GET /middle/token/get.json取token,POST /auth/user/getUserBasicInfo以Bearer令牌换用户基本信息),经用户服务校验身份后按需同步建档;响应结构与门户跳转验签完全一致(双阶段LOGIN/SET_PASSWORD)。仅Java版后端提供本接口,Python版返回404、功能未启用返回400,前端探测失败静默回落账号密码登录。
  231. security: []
  232. parameters:
  233. - $ref: '../components/parameters.yaml#/XRequestId'
  234. responses:
  235. '200':
  236. description: 探测结果(结构与PortalVerify一致)
  237. content:
  238. application/json:
  239. schema:
  240. type: object
  241. required: [code, message, data, requestId]
  242. properties:
  243. code: {type: string}
  244. message: {type: string}
  245. requestId: {type: string}
  246. data:
  247. type: object
  248. required: [phase, username, realName]
  249. properties:
  250. phase: {type: string, enum: [LOGIN, SET_PASSWORD], description: SET_PASSWORD时携带一次性设密票据portalTicket及机构选择数据}
  251. username: {type: string}
  252. realName: {type: string}
  253. portalTicket: {type: string}
  254. suggestedOrganizationId: {type: string, nullable: true}
  255. roles:
  256. type: array
  257. description: 挂载角色简表(契约1.53 密码即角色);挂载≥2时返回,设密界面逐角色分配密码(恰一个使用用户密码)。
  258. items:
  259. type: object
  260. required: [id, roleName]
  261. additionalProperties: false
  262. properties:
  263. id: {type: string}
  264. roleName: {type: string}
  265. organizations:
  266. type: array
  267. items:
  268. type: object
  269. required: [id, orgCode, orgName, orgPath]
  270. additionalProperties: false
  271. properties:
  272. id: {type: string}
  273. orgCode: {type: string}
  274. orgName: {type: string}
  275. orgPath: {type: string}
  276. '400':
  277. $ref: '../components/responses.yaml#/InvalidArgument'
  278. '401':
  279. $ref: '../components/responses.yaml#/AuthenticationError'
  280. '500':
  281. $ref: '../components/responses.yaml#/InternalError'
  282. PortalSetupPassword:
  283. post:
  284. operationId: setupPortalPassword
  285. summary: 门户用户首次设置独立密码并登录
  286. description: 票据一次性且5分钟内有效;设置成功后签发访问令牌。可选携带organizationId同步设置用户所在机构(须为有效且启用的机构;缺省不改变)。多角色首登可携带rolePasswords逐角色分配密码(契约1.53),设密后以「使用用户密码」的角色直接签发进入。
  287. security: []
  288. parameters:
  289. - $ref: '../components/parameters.yaml#/XRequestId'
  290. requestBody:
  291. required: true
  292. content:
  293. application/json:
  294. schema:
  295. type: object
  296. required: [portalTicket, newPassword, keepSignedIn]
  297. additionalProperties: false
  298. properties:
  299. portalTicket: {type: string, minLength: 1}
  300. newPassword: {type: string, minLength: 1}
  301. keepSignedIn: {type: boolean}
  302. organizationId: {type: string, description: 用户自选的所在机构ID(verify响应organizations中的id);缺省不改变}
  303. rolePasswords:
  304. type: array
  305. description: 角色密码分配(契约1.53 密码即角色);挂载≥2角色时须提交——恰一个password=null(使用用户密码),其余独立密码互异且不等于newPassword,冲突400 PASSWORD_CONFLICT。
  306. items: {$ref: '../components/schemas.yaml#/RolePasswordAssignment'}
  307. responses:
  308. '200':
  309. description: 设密并登录成功
  310. content:
  311. application/json:
  312. schema:
  313. $ref: '../components/schemas.yaml#/LoginResponse'
  314. '400':
  315. $ref: '../components/responses.yaml#/InvalidArgument'
  316. '403':
  317. $ref: '../components/responses.yaml#/Forbidden'
  318. '500':
  319. $ref: '../components/responses.yaml#/InternalError'