如何为 RPyC 服务器实现用户名密码验证器

How to implement username password authenticator for RPyC server

我正在尝试通过用户名和密码保护我的 RpyC 服务器连接。文档确实显示了 example,但它太简短了。没有详细说明密码是如何从客户端传递的。有人知道怎么做吗?提前致谢。

回答我自己的问题:

我不得不在客户端覆盖 RPyC 的一些内部方法以实现所需的行为。我不知道是否存在更清洁的解决方案,但这似乎是一个合理的解决方案。

服务器:

import rpyc
from rpyc.utils.authenticators import AuthenticationError

def magic_word_authenticator(sock):
    if sock.recv(5).decode() != "Ma6ik":
        raise AuthenticationError("wrong magic word")
    return sock, None

class SecuredService(rpyc.Service):

    def exposed_secured_op(self):
        return 'Secret String'

rpyc.ThreadedServer(
    service=SecuredService, hostname='localhost',
    port=18812, authenticator=magic_word_authenticator
).start()

客户:

import rpyc
import traceback


class AuthSocketStream(rpyc.SocketStream):

    @classmethod
    def connect(cls, *args, authorizer=None, **kwargs):
        stream_obj =  super().connect(*args, **kwargs)

        if callable(authorizer):
            authorizer(stream_obj.sock)

        return stream_obj


def rpyc_connect(host, port, service=rpyc.VoidService, config={}, ipv6=False, keepalive=False, authorizer=None):
    s = AuthSocketStream.connect(
            host, port, ipv6=ipv6, keepalive=keepalive,
            authorizer=authorizer
    )

    return rpyc.connect_stream(s, service, config)

print('With correct authorizer')

conn1 = rpyc_connect(
        'localhost', 18812, authorizer=lambda sock: sock.send('Ma6ik'.encode())
)

print(conn1.root.secured_op())

print('With wrong authorizer')

conn2 = rpyc_connect(
        'localhost', 18812, authorizer=lambda sock: sock.send('Invalid'.encode())
)

try:
    conn2.root
except Exception:
    print(traceback.format_exc())


print('With no authorizer')

conn3 = rpyc_connect(
        'localhost', 18812
)

try:
    conn3.root
except Exception:
    print(traceback.format_exc())

客户端控制台日志:

With correct authorizer
Secret String
With wrong authorizer
Traceback (most recent call last):
  File "/home/client.py", line 40, in <module>
    conn2.root
  File "/usr/lib/python3.10/site-packages/rpyc/core/protocol.py", line 507, in root
    self._remote_root = self.sync_request(consts.HANDLE_GETROOT)
  File "/usr/lib/python3.10/site-packages/rpyc/core/protocol.py", line 474, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/lib/python3.10/site-packages/rpyc/core/async_.py", line 101, in value
    self.wait()
  File "/usr/lib/python3.10/site-packages/rpyc/core/async_.py", line 48, in wait
    self._conn.serve(self._ttl)
  File "/usr/lib/python3.10/site-packages/rpyc/core/protocol.py", line 387, in serve
    data = self._channel.poll(timeout) and self._channel.recv()
  File "/usr/lib/python3.10/site-packages/rpyc/core/channel.py", line 55, in recv
    header = self.stream.read(self.FRAME_HEADER.size)
  File "/usr/lib/python3.10/site-packages/rpyc/core/stream.py", line 260, in read
    raise EOFError("connection closed by peer")
EOFError: connection closed by peer

With no authorizer
Traceback (most recent call last):
  File "/home/client.py", line 52, in <module>
    conn3.root
  File "/usr/lib/python3.10/site-packages/rpyc/core/protocol.py", line 507, in root
    self._remote_root = self.sync_request(consts.HANDLE_GETROOT)
  File "/usr/lib/python3.10/site-packages/rpyc/core/protocol.py", line 474, in sync_request
    return self.async_request(handler, *args, timeout=timeout).value
  File "/usr/lib/python3.10/site-packages/rpyc/core/async_.py", line 101, in value
    self.wait()
  File "/usr/lib/python3.10/site-packages/rpyc/core/async_.py", line 48, in wait
    self._conn.serve(self._ttl)
  File "/usr/lib/python3.10/site-packages/rpyc/core/protocol.py", line 387, in serve
    data = self._channel.poll(timeout) and self._channel.recv()
  File "/usr/lib/python3.10/site-packages/rpyc/core/channel.py", line 55, in recv
    header = self.stream.read(self.FRAME_HEADER.size)
  File "/usr/lib/python3.10/site-packages/rpyc/core/stream.py", line 260, in read
    raise EOFError("connection closed by peer")
EOFError: connection closed by peer