JumpServer PAM 账号密码查询 API:Python 集成指南(account-secret 接口实战)
2026/9/10 13:11:38 网站建设 项目流程

JumpServer PAM 账号密码查询 API:Python 集成指南(account-secret 接口实战)

【免费下载链接】jumpserverJumpServer is an open-source Privileged Access Management (PAM) platform that provides DevOps and IT teams with on-demand and secure access to SSH, RDP, Kubernetes, Database and RemoteApp endpoints through a web browser.项目地址: https://gitcode.com/GitHub_Trending/ju/jumpserver

JumpServer 作为开源特权访问管理(PAM)平台,为运维和 IT 团队提供了统一的账号资产托管与安全审计能力。当外部业务系统需要获取托管资产的账号密码时,JumpServer 提供了 RESTful 的集成应用(Integration Application)接口。本文围绕 apps/accounts/demos/python/README.zh-hans.md 文档,结合 Python 示例代码 与仓库源码,完整讲解账号密码查询接口的请求方式、参数约定、签名认证原理、服务端校验逻辑与常见问题,读完即可编写出可安全接入 JumpServer 的 Python 客户端。

1. 接口概览

本 API 提供 PAM 资产账号密码查询服务,支持 RESTful 风格调用,并以 JSON 格式返回数据。它的本质是"集成应用"(Integration Application)能力的一部分:管理员先在 PAM 平台中创建应用并绑定账号,外部系统再凭应用的 Key 以 HTTP 签名方式换取指定资产的账号密码。

  • 请求方式:GET
  • 接口路径:api/v1/accounts/integration-applications/account-secret/
  • 返回格式:application/json

1.1 请求参数

参数名类型必填说明
assetstr资产名称
accountstr账号名称

1.2 响应示例

{ "id": "72b0b0aa-ad82-4182-a631-ae4865e8ae0e", "secret": "123456" }

其中id为集成应用(即调用方)的 ID,secret为查询到的账号密码。

说明:响应中的id对应调用方集成应用自身,而不是资产或账号 ID。这一行为由 application.py 中的Response(data={'id': request.user.id, 'secret': secret})决定。

2. 环境要求

官方 Python 示例的运行环境要求如下:

  • Python 3.11+
  • requests==2.31.0
  • httpsig==1.3.0

其中httpsig用于实现 HTTP 签名认证(HTTP Signature),requests负责发起 HTTP 请求。需要注意的是,setup.py中的python_requires='>=3.6'是 SDK 打包时的最低声明,而官方 Demo 面向 Python 3.11+ 验证,生产使用建议以 3.11+ 为准。

3. 运行示例:API Key 从哪来

3.1 在 PAM 中创建应用

Q: API Key 如何获取?

A: 您可以在PAM - 应用管理中创建应用,以生成KEY_IDKEY_SECRET

在 JumpServer 中,这个"应用"对应数据模型 IntegrationApplication,其核心字段包括:

  • name:应用名称,与组织组合后唯一(unique_together = [('name', 'org_id')]);
  • secret:应用的密钥(即KEY_SECRET),加密存储(EncryptTextField);
  • accounts:该应用可查询的账号集合(JSONManyToManyField),即权限边界——应用只能查询被授权绑定的账号
  • ip_group:允许调用来源的 IP 分组白名单;
  • is_active:应用是否启用。

应用创建后,应用 ID 即为KEY_IDsecret即为KEY_SECRET。密钥可通过refresh_secret重新生成(见 application.py,random_string(36)生成 36 位随机串),刷新后旧密钥立即失效,客户端需同步更新。

3.2 快速运行官方 Demo

仓库提供了开箱即用的示例 demo.py,支持通过环境变量注入配置:

export API_URL="http://127.0.0.1:8080" export API_KEY_ID="72b0b0aa-ad82-4182-a631-ae4865e8ae0e" export API_KEY_SECRET="6fuSO7P1m4cj8SSlgaYdblOjNAmnxDVD7tr8" export ORG_ID="00000000-0000-0000-0000-000000000002" python demo.py

Demo 中提供的默认值仅为占位示例,实际使用时请替换为在应用管理中创建的真实凭据。运行时输出如下(查询资产ubuntu_dockerroot账号):

# demo.py 核心调用 if __name__ == "__main__": client = APIClient() result = client.get_account_secret(asset="ubuntu_docker", account="root") print(result)

4. 签名认证原理:HTTP Signature + HMAC-SHA256

该接口并不使用简单的 Token 或 Basic Auth,而是采用HTTP Signature(httpsig)签名方案。Demo 中认证对象的构建方式如下:

from httpsig.requests_auth import HTTPSignatureAuth self.auth = HTTPSignatureAuth( key_id=KEY_ID, secret=KEY_SECRET, algorithm='hmac-sha256', headers=['(request-target)', 'accept', 'date', 'x-jms-org'] )

签名会覆盖以下请求要素,防止请求被篡改或重放:

  • (request-target):请求方法 + 路径(get /api/v1/accounts/integration-applications/account-secret/);
  • acceptapplication/json
  • date:RFC 7231 格式的 GMT 时间戳;
  • x-jms-org:组织 ID。

对应的请求头由 Demo 组装:

headers = { 'Accept': 'application/json', 'X-JMS-ORG': ORG_ID, 'Date': datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'), 'X-Source': 'jms-pam' }

其中Date必须与签名时使用的date一致,格式为%a, %d %b %Y %H:%M:%S GMT(如Tue, 09 Sep 2026 02:41:38 GMT)。跳板机等中间层不会影响 httpsig 对(request-target)的规范化计算,因此无需额外处理。

此外,仓库还提供了更完整的封装 jms_pam/main.py:

  • SecretRequest:对asset/asset_id/account/account_id做参数校验;
  • Secret:统一封装secret与错误描述descvalid = not desc
  • JumpServerPAM:客户端门面,_get_auth()中签名头为['(request-target)', 'accept', 'date']send()负责拼接 URL、发起请求并解析响应。

该模块可通过 setup.py 打包为jms-pam库(pip install .),供业务系统以库的方式集成。

5. 服务端校验逻辑与参数进阶

虽然 README 只列出了asset+account两个参数,但服务端实际支持四种参数的组合查询。序列化器定义位于 service.py:

class IntegrationAccountSecretSerializer(serializers.Serializer): asset = serializers.CharField(required=False, allow_blank=True) asset_id = serializers.UUIDField(required=False, allow_null=True) account = serializers.CharField(required=False, allow_blank=True) account_id = serializers.UUIDField(required=False, allow_null=True)
  • 提供account_id时,必须唯一提供,且不能再传asset/asset_id/account
  • 提供account(账号名称)时,必须同时提供asset(资产名称)或asset_id(资产 ID)之一;
  • account_idasset_id不允许同时出现;
  • 至少需要提供assetasset_id之一,以及accountaccount_id之一。

服务端命中账号的查找逻辑见 application.py:优先按account_id精确匹配;否则按account名称,再叠加asset_idasset__name过滤,最后统一叠加应用绑定的账号集合做权限过滤,返回distinct().first()

请求处理主流程位于 application.py:

  1. 参数校验失败直接返回400{'error': serializer.errors}
  2. request.user作为集成应用,调用service.get_account(**serializer.data)查询账号,查不到则抛出JMSException('Not found')
  3. 每次查询都会写入IntegrationApplicationLog审计日志(记录远端 IP、服务名、账号与资产信息,见 audits),满足 PAM 审计要求;
  4. 若系统配置了SECURITY_DISABLE_VIEW_SECRET(禁止查看密码),则secret字段返回None——即使查询成功也不返回明文密码。

鉴权方面,get_account_secret使用RBACPermission,要求调用方拥有accounts.view_integrationapplication权限;应用模型 is_valid / is_authenticated 直接与is_active绑定,即应用被停用后接口立即拒绝服务。

6. 完整可运行示例

以下代码综合 README 参数表与仓库实现,形成最小可运行客户端(可与demo.py对比使用):

import os import requests from datetime import datetime from httpsig.requests_auth import HTTPSignatureAuth API_URL = os.getenv("API_URL", "http://127.0.0.1:8080") KEY_ID = os.getenv("API_KEY_ID", "") KEY_SECRET = os.getenv("API_KEY_SECRET", "") ORG_ID = os.getenv("ORG_ID", "00000000-0000-0000-0000-000000000002") class APIClient: def __init__(self): self.session = requests.Session() self.auth = HTTPSignatureAuth( key_id=KEY_ID, secret=KEY_SECRET, algorithm='hmac-sha256', headers=['(request-target)', 'accept', 'date', 'x-jms-org'] ) def get_account_secret(self, asset, account): url = f"{API_URL}/api/v1/accounts/integration-applications/account-secret/" headers = { 'Accept': 'application/json', 'X-JMS-ORG': ORG_ID, 'Date': datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT'), 'X-Source': 'jms-pam' } params = {"asset": asset, "account": account} response = self.session.get( url, auth=self.auth, headers=headers, params=params, timeout=10 ) response.raise_for_status() return response.json() if __name__ == "__main__": client = APIClient() print(client.get_account_secret(asset="ubuntu_docker", account="root"))

调用时替换API_URLKEY_IDKEY_SECRET为真实环境值;若查询的是组织内的资产,务必让ORG_IDX-JMS-ORG保持一致,否则服务端会在签名校验阶段因x-jms-org不一致而拒绝请求。

7. 常见问题(FAQ)与排查指引

  • Q: API Key 如何获取?A: 在 PAM - 应用管理中创建应用,生成KEY_IDKEY_SECRET;创建后可在应用详情中查看一次性 Secret,也可通过刷新接口重新生成。
  • Q: 返回 401/签名失败?检查三处:KEY_SECRET是否与应用当前 Secret 一致(刷新过则需同步);Date头是否为 GMT 格式且与签名时一致;X-JMS-ORG是否与签名头列表中的x-jms-org匹配。
  • Q: 返回 "Account not found"?确认账号名/资产名拼写正确,且该账号已被授权绑定到集成应用(accounts字段);跨组织查询需使用正确的ORG_ID
  • Q: 返回 200 但secret为 null?这是服务端开启了SECURITY_DISABLE_VIEW_SECRET的安全配置,属于预期行为,需由管理员评估后调整。
  • Q: 请求来源被拒绝?应用配置了ip_group白名单,请确认发起请求的出口 IP 在允许范围内,且应用处于is_active启用状态。

8. 版本历史

版本号变更内容日期
1.0.0初始版本2025-02-11

延伸阅读

  • 官方 Python 示例:demo.py 与 jms_pam/main.py
  • 服务端视图实现:application.py
  • 集成应用模型:application.py
  • 参数序列化器:service.py
  • 路由注册:urls.py
  • 同接口的 curl / Go / Java / Node 实现见 apps/accounts/demos 目录,便于对照迁移

【免费下载链接】jumpserverJumpServer is an open-source Privileged Access Management (PAM) platform that provides DevOps and IT teams with on-demand and secure access to SSH, RDP, Kubernetes, Database and RemoteApp endpoints through a web browser.项目地址: https://gitcode.com/GitHub_Trending/ju/jumpserver

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询