Captcha: get: operationId: fetchCaptcha summary: 登录图片验证码签发(安全需求4) description: 环境变量DMS_CAPTCHA_ENABLED(双版同名,缺省true)开启时返回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' Login: post: operationId: login summary: 用户登录 description: 验证码开启(DMS_CAPTCHA_ENABLED,缺省true)时请求体必须且只能包含五键(追加captchaId/captchaCode),验证码校验先于用户查询与锁定检查、一次性消费不计入登录失败锁定,错误返回400 INVALID_CAPTCHA;关闭时保持三键(username/password/keepSignedIn)。 security: [] parameters: - $ref: '../components/parameters.yaml#/XRequestId' requestBody: required: true content: application/json: schema: $ref: '../components/schemas.yaml#/LoginRequest' responses: '200': description: 登录成功 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} 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同步设置用户所在机构(须为有效且启用的机构;缺省不改变)。 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);缺省不改变} 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'