| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- Captcha:
- get:
- operationId: fetchCaptcha
- summary: 登录图片验证码签发(安全需求4)
- description: 环境变量DMS_CAPTCHA_ENABLED(双版同名,1.40起缺省false)开启时返回captchaId与data:image/png;base64图片(132×44、4位字符剔除易混淆0O1I、120秒过期、一次性消费);关闭时仅返回enabled=false。登录页据enabled决定是否展示验证码输入;请求与响应均不缓存。
- security: []
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- responses:
- '200':
- description: 验证码签发结果
- content:
- application/json:
- schema:
- type: object
- required: [code, message, data, requestId]
- properties:
- code: {type: string, enum: [OK]}
- message: {type: string, enum: [success]}
- requestId: {type: string, format: uuid}
- data:
- type: object
- required: [enabled, passwordLoginDisabled]
- additionalProperties: false
- properties:
- enabled: {type: boolean, description: 验证码开关当前值}
- passwordLoginDisabled: {type: boolean, description: 禁用用户名密码登录开关回显(1.39安全管控,仅Java版);true时登录页隐藏账号密码表单,POST /auth/login一律403}
- captchaId: {type: string, description: 验证码标识,登录时原样携带;enabled=true时必返}
- image: {type: string, description: data:image/png;base64图片,img标签src直接使用;enabled=true时必返}
- '500':
- $ref: '../components/responses.yaml#/InternalError'
- ResetPasswordRequest:
- post:
- operationId: createResetPasswordRequest
- summary: 登录前提交重置密码申请(契约1.49)
- 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「该账号密码已重置,请通过单点登录进入并重新设置密码」。
- security: []
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- additionalProperties: false
- required: [username]
- properties:
- username: {type: string, description: 用户名或姓名。}
- captchaId: {type: string, description: 验证码标识(验证码开启时必填)。}
- captchaCode: {type: string, description: 验证码字符(验证码开启时必填)。}
- responses:
- '200':
- description: 申请已受理
- content:
- application/json:
- schema:
- type: object
- required: [code, message, data, requestId]
- properties:
- code: {type: string, enum: [OK]}
- message: {type: string, enum: [success]}
- requestId: {type: string, format: uuid}
- data:
- type: object
- required: [requestId, notified]
- additionalProperties: false
- properties:
- requestId: {$ref: '#/StringId'}
- notified: {type: integer, minimum: 1, description: 收到待办通知的审批人数。}
- '400': {$ref: '../components/responses.yaml#/BadRequest'}
- '409': {$ref: '../components/responses.yaml#/Conflict'}
- '500': {$ref: '../components/responses.yaml#/InternalError'}
- Login:
- post:
- operationId: login
- summary: 用户登录
- 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留痕。
- security: []
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: '../components/schemas.yaml#/LoginRequest'
- responses:
- '200':
- description: 登录成功(多角色未带roleId返回RoleSelectionData选择步骤;密码被重置审批清空返回SetupPasswordPhaseData设密步骤)
- content:
- application/json:
- schema:
- $ref: '../components/schemas.yaml#/LoginResponse'
- '400':
- description: 请求参数错误或验证码缺失/错误/过期(INVALID_CAPTCHA,安全需求4)
- content:
- application/json:
- schema:
- $ref: '../components/schemas.yaml#/ErrorResponse'
- '401':
- $ref: '../components/responses.yaml#/AuthenticationError'
- '403':
- $ref: '../components/responses.yaml#/Forbidden'
- '500':
- $ref: '../components/responses.yaml#/InternalError'
- Logout:
- post:
- operationId: logout
- summary: 注销并使当前用户旧Token失效
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- responses:
- '200':
- description: 注销成功
- content:
- application/json:
- schema:
- $ref: '../components/schemas.yaml#/EmptySuccessResponse'
- '400':
- $ref: '../components/responses.yaml#/InvalidArgument'
- '401':
- $ref: '../components/responses.yaml#/AuthenticationError'
- '403':
- $ref: '../components/responses.yaml#/Forbidden'
- '500':
- $ref: '../components/responses.yaml#/InternalError'
- Reauth:
- post:
- operationId: reauth
- summary: 敏感操作二次认证(重输登录密码换取5分钟reauth令牌)
- description: 登录态下重输登录密码,签发type=reauth的短时令牌(绑定sub与authVersion,不可冒充访问令牌);不写审计、不计入登录失败锁定。
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- required: [password]
- additionalProperties: false
- properties:
- password: {type: string, format: password, minLength: 1}
- responses:
- '200':
- description: 二次认证成功
- content:
- application/json:
- schema:
- type: object
- required: [code, message, data, requestId]
- properties:
- code: {type: string, enum: [OK]}
- message: {type: string, enum: [success]}
- requestId: {type: string, format: uuid}
- data:
- type: object
- required: [reauthToken, expiresIn]
- properties:
- reauthToken: {type: string, description: 二次认证令牌,经X-DMS-Reauth-Token请求头携带}
- expiresIn: {type: integer, enum: [300], description: 固定300秒(5分钟)}
- '400':
- $ref: '../components/responses.yaml#/InvalidArgument'
- '401':
- $ref: '../components/responses.yaml#/AuthenticationError'
- '500':
- $ref: '../components/responses.yaml#/InternalError'
- PortalVerify:
- post:
- operationId: verifyPortalLaunch
- summary: 统一门户跳转验签
- description: 透传浏览器地址栏query串验签,按需落库建档并同步组织信息;返回跳转阶段,首次进入需设置独立密码。
- security: []
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- required: [query]
- additionalProperties: false
- properties:
- query: {type: string, minLength: 1, description: 门户跳转链接的完整query串}
- responses:
- '200':
- description: 验签结果
- content:
- application/json:
- schema:
- type: object
- required: [code, message, data, requestId]
- properties:
- code: {type: string}
- message: {type: string}
- requestId: {type: string}
- data:
- type: object
- required: [phase, username, realName]
- properties:
- phase: {type: string, enum: [LOGIN, SET_PASSWORD], description: SET_PASSWORD时携带一次性设密票据portalTicket及机构选择数据}
- username: {type: string}
- realName: {type: string}
- portalTicket: {type: string}
- suggestedOrganizationId: {type: string, nullable: true, description: 按对端机构名/默认组织推断的用户当前机构ID(可能为空),前端预选用}
- organizations:
- type: array
- description: 仅SET_PASSWORD阶段返回;本系统机构树与大系统可能不一致(用户按需同步、机构不自动同步),设密时由用户自选所在机构
- items:
- type: object
- required: [id, orgCode, orgName, orgPath]
- additionalProperties: false
- properties:
- id: {type: string}
- orgCode: {type: string}
- orgName: {type: string}
- orgPath: {type: string}
- '400':
- $ref: '../components/responses.yaml#/InvalidArgument'
- '403':
- $ref: '../components/responses.yaml#/Forbidden'
- '500':
- $ref: '../components/responses.yaml#/InternalError'
- PortalProxyVerify:
- post:
- operationId: verifyProxySso
- summary: 本地单点登录代理探测(仅Java版提供)
- description: 令牌取自本机单点登录代理(REST直连:GET /middle/token/get.json取token,POST /auth/user/getUserBasicInfo以Bearer令牌换用户基本信息),经用户服务校验身份后按需同步建档;响应结构与门户跳转验签完全一致(双阶段LOGIN/SET_PASSWORD)。仅Java版后端提供本接口,Python版返回404、功能未启用返回400,前端探测失败静默回落账号密码登录。
- security: []
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- responses:
- '200':
- description: 探测结果(结构与PortalVerify一致)
- content:
- application/json:
- schema:
- type: object
- required: [code, message, data, requestId]
- properties:
- code: {type: string}
- message: {type: string}
- requestId: {type: string}
- data:
- type: object
- required: [phase, username, realName]
- properties:
- phase: {type: string, enum: [LOGIN, SET_PASSWORD], description: SET_PASSWORD时携带一次性设密票据portalTicket及机构选择数据}
- username: {type: string}
- realName: {type: string}
- portalTicket: {type: string}
- suggestedOrganizationId: {type: string, nullable: true}
- roles:
- type: array
- description: 挂载角色简表(契约1.53 密码即角色);挂载≥2时返回,设密界面逐角色分配密码(恰一个使用用户密码)。
- items:
- type: object
- required: [id, roleName]
- additionalProperties: false
- properties:
- id: {type: string}
- roleName: {type: string}
- organizations:
- type: array
- items:
- type: object
- required: [id, orgCode, orgName, orgPath]
- additionalProperties: false
- properties:
- id: {type: string}
- orgCode: {type: string}
- orgName: {type: string}
- orgPath: {type: string}
- '400':
- $ref: '../components/responses.yaml#/InvalidArgument'
- '401':
- $ref: '../components/responses.yaml#/AuthenticationError'
- '500':
- $ref: '../components/responses.yaml#/InternalError'
- PortalSetupPassword:
- post:
- operationId: setupPortalPassword
- summary: 门户用户首次设置独立密码并登录
- description: 票据一次性且5分钟内有效;设置成功后签发访问令牌。可选携带organizationId同步设置用户所在机构(须为有效且启用的机构;缺省不改变)。多角色首登可携带rolePasswords逐角色分配密码(契约1.53),设密后以「使用用户密码」的角色直接签发进入。
- security: []
- parameters:
- - $ref: '../components/parameters.yaml#/XRequestId'
- requestBody:
- required: true
- content:
- application/json:
- schema:
- type: object
- required: [portalTicket, newPassword, keepSignedIn]
- additionalProperties: false
- properties:
- portalTicket: {type: string, minLength: 1}
- newPassword: {type: string, minLength: 1}
- keepSignedIn: {type: boolean}
- organizationId: {type: string, description: 用户自选的所在机构ID(verify响应organizations中的id);缺省不改变}
- rolePasswords:
- type: array
- description: 角色密码分配(契约1.53 密码即角色);挂载≥2角色时须提交——恰一个password=null(使用用户密码),其余独立密码互异且不等于newPassword,冲突400 PASSWORD_CONFLICT。
- items: {$ref: '../components/schemas.yaml#/RolePasswordAssignment'}
- responses:
- '200':
- description: 设密并登录成功
- content:
- application/json:
- schema:
- $ref: '../components/schemas.yaml#/LoginResponse'
- '400':
- $ref: '../components/responses.yaml#/InvalidArgument'
- '403':
- $ref: '../components/responses.yaml#/Forbidden'
- '500':
- $ref: '../components/responses.yaml#/InternalError'
|