You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python脚本在Ejabberd XMPP服务器注册新用户?

解决Ejabberd通过xmpppy注册用户权限拒绝问题

问题分析

你遇到的Access denied by service policy错误,本质是因为你用普通的XMPP注册IQ指令(jabber:iq:register)尝试创建用户,但Ejabberd默认这个指令是给匿名用户自助注册用的,已认证的管理员账号无法通过这个路径创建用户。即使你设置了access_rules里的register: allow: all,也只适用于匿名注册场景,管理员创建用户需要使用Ejabberd的Admin API。

解决方案

1. 确认Ejabberd Admin API权限配置

打开/opt/ejabberd/conf/ejabberd.yml,确保api_permissions中允许管理员执行创建用户的操作:

api_permissions:
  "admin access":
    who:
      - access:
          allow:
            - user: "admin@myserver.com" # 替换为你的管理员账号
      - oauth:
          scope: "ejabberd:admin"
          access:
            allow:
              - user: "admin@myserver.com"
    what:
      - "register"
      - "create_user"
      - "all" # 测试阶段可直接赋予全部权限

同时确保mod_admin_extra模块已启用(该模块提供创建用户的管理命令),在modules节点添加:

modules:
  mod_admin_extra: {}

2. 修改Python脚本使用Admin API创建用户

替换原脚本中的注册逻辑,改用Ejabberd的XMPP Admin命令(命名空间http://jabber.org/protocol/admin)来创建用户:

#!/usr/bin/python3
import xmpp

server = "myserver.com"
admin_username = "admin@myserver.com"
admin_password = "password1234"
new_username = "newuser" # 仅需用户名,无需带域名
new_password = "newuserpassword1234"

def register_user(server, admin_username, admin_password, new_username, new_password):
    admin_jid = xmpp.protocol.JID(admin_username)
    client = xmpp.Client(server=server, debug=[])
    
    # 启用TLS加密连接(Ejabberd默认要求)
    conn_result = client.connect(secure=True)
    if not conn_result:
        print("连接服务器失败")
        return

    # 管理员账号认证
    auth_result = client.auth(user=admin_jid.getNode(), password=admin_password, resource="admin-cli")
    if not auth_result:
        print("管理员认证失败")
        client.disconnect()
        return

    # 构造Admin API创建用户的IQ请求
    iq = xmpp.Iq(to=server, typ='set')
    query = iq.addChild("query", namespace="http://jabber.org/protocol/admin")
    query.addChild("add_user")
    query.addChild("username", payload=[new_username])
    query.addChild("host", payload=[server])
    query.addChild("password", payload=[new_password])

    result = client.SendAndWaitForResponse(iq)

    if result and result.getType() == 'result':
        print(f"用户 {new_username}@{server} 注册成功")
    else:
        print("错误信息:", result)
        print("用户注册失败")

    client.disconnect()

if __name__ == '__main__':
    register_user(server, admin_username, admin_password, new_username, new_password)

3. 额外检查项

  • 确保Ejabberd的XMPP端口(默认5222)对外开放,脚本能正常连接。
  • 若仍有问题,可在ejabberd.yml中开启debug日志,查看更详细的权限拒绝原因:
loglevel: 5
log_rotate_size: 10485760
log_rotate_date: ""
log_rotate_count: 1
log_rate_limit: 100

关键说明

  • 普通的jabber:iq:register仅适用于匿名用户自助注册,管理员必须通过Admin API执行用户创建操作。
  • 脚本中new_username不需要带域名,因为指令中单独指定了host字段对应服务器域名。

内容的提问来源于stack exchange,提问作者Bryan Yep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:30:24