首页 > 解决方案 > 在 Python 脚本上调用 HTTPS 的 Ejabberd 外部身份验证错误

问题描述

我正在使用调用 HTTPS 端点的 python 脚本在 ejabberd 中实现外部身份验证。但它给了我这个错误:

    [17824] [ERROR] Error authenticating user
Traceback (most recent call last):
  File "/opt/ejabberd-18.09/conf/external_auth.py", line 25, in auth_login
    response = json.load(urllib2.urlopen(request))
  File "/usr/lib/python2.7/urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 429, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 452, in _open
    'unknown_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 407, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1266, in unknown_open
    raise URLError('unknown url type: %s' % type)
URLError: <urlopen error unknown url type: https>

下面的 extauth 脚本:

#!/usr/bin/env python

import sys
import struct
import logging
import os
import urllib2
import urllib
import json

LOGFILE = '/var/log/ejabberd/extauth.log'
ERRFILE = '/var/log/ejabberd/extauth.err'
AUTH_URL= "https://www.mocky.io/v2/5185415ba171ea3a00704eed"

def auth_login(token):
    try:
        headers = {'Content-Type': 'application/json'}
        payload = {'token': token }

        url = "{}".format(AUTH_URL) 
        logging.info('Url formatted: %s', url)
        request = urllib2.Request(url, json.dumps(payload), headers)
        response = json.load(urllib2.urlopen(request))
        logging.info('Response: %s', response)
    except urllib2.HTTPError as http_err:
        return False
    except Exception as e:
        logging.exception("Error authenticating user")
        return False

    return response['valid']

def read():
    (pkt_size,) = struct.unpack('>H', sys.stdin.read(2))
    pkt = sys.stdin.read(pkt_size).split(':')
    cmd = pkt[0]
    args_num = len(pkt) - 1
    if cmd == 'auth' and args_num >= 3:
        logging.debug('User trying to auth')
        is_valid_user = auth_login(pkt[3])

        if is_valid_user:
            logging.debug('Logged User :'+pkt[1]+":"+pkt[2]+":"+pkt[3])
            write(True)
        else:
            logging.info('Error on authenticating user:'+pkt[1]+":"+pkt[2]+":"+pkt[3])
            write(False)
    elif cmd == 'isuser' and args_num == 2:
        logging.debug('isuser received')
        logging.debug(pkt[0]+":"+pkt[1])
        write(False)
    elif cmd == 'setpass' and args_num >= 3:
        logging.debug('setpass received')
        logging.debug(pkt[0]+":"+pkt[1]+":"+pkt[2])
        write(False)
    elif cmd == 'tryregister' and args_num >= 3:
        logging.debug('tryregister received')
        logging.debug(pkt[0]+":"+pkt[1]+":"+pkt[2])
        write(False)
    elif cmd == 'removeuser' and args_num == 2:
        logging.debug('removeuser received')
        logging.debug(pkt[0]+":"+pkt[1])
        write(False)
    elif cmd == 'removeuser3' and args_num >= 3:
        logging.debug('removeuser3 received')
        logging.debug(pkt[0]+":"+pkt[1]+":"+pkt[2])
        write(False)
    else:
        write(False)
    read()
def loop():
    while True:
        try:
            read()
        except KeyboardInterrupt:
            logging.info('Terminating by user input')
            break
        except Exception as e:
            logging.exception('Input error: ')
            break

if __name__ == "__main__":
    PID = str(os.getpid())
    FMT = '[%(asctime)s] ['+PID+'] [%(levelname)s] %(message)s'
    sys.stderr = open(ERRFILE, 'a+')
    logging.basicConfig(level=logging.DEBUG, format=FMT, filename=LOGFILE)
    try:
        loop()
    except struct.error:
        pass

在 ejabberd.yml 的主机配置部分中,extauth_program 属性定义为:

extauth_program: "python /opt/ejabberd-18.09/conf/external_auth.py"

实际上我正在将 Ejabberd 版本从 16.01 升级到 18.09。在 Ejabberd 16.01 中,此代码运行正常,当我在终端上调用此脚本时,它也运行正常。有人可以帮我吗?

标签: pythonxmppejabberd

解决方案


推荐阅读