Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions zmq/auth/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@


class AsyncioAuthenticator(Authenticator):
"""ZAP authentication for use in the asyncio IO loop"""
"""ZAP authentication for use in the asyncio IO loop

.. versionadded:: 27.2
Multiple authenticators can now run in the same process
by specifying different socket addresses in ``start()``.
See :class:`zmq.auth.Authenticator` for details and examples.
"""

__poller: Optional[Poller]
__task: Any
Expand Down Expand Up @@ -46,9 +52,20 @@ async def __handle_zap(self) -> None:
msg = self.zap_socket.recv_multipart()
await self.handle_zap_message(msg)

def start(self) -> None:
"""Start ZAP authentication"""
super().start()
def start(self, socket_addr="inproc://zeromq.zap.01") -> None:
"""Start ZAP authentication

Parameters
----------
socket_addr : str, optional
The address to bind the ZAP socket to.
Default is "inproc://zeromq.zap.01"

.. versionadded:: 27.2
Support for custom socket addresses, enabling multiple
authenticators in the same process.
"""
super().start(socket_addr)
self.__poller = Poller()
self.__poller.register(self.zap_socket, zmq.POLLIN)
self.__task = asyncio.ensure_future(self.__handle_zap())
Expand Down
33 changes: 30 additions & 3 deletions zmq/auth/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ class Authenticator:
main thread, other authentication classes (such as :mod:`zmq.auth.thread`)
are provided.

Multiple Authenticators
-----------------------

.. versionadded:: 27.2

Multiple authenticators can run in the same process by binding to different
ZAP socket addresses. This allows different authentication policies for
different sets of sockets within the same application::

# Create two authenticators with different policies
frontend_auth = zmq.auth.asyncio.AsyncioAuthenticator()
frontend_auth.start(socket_addr="inproc://zap-frontend")

backend_auth = zmq.auth.asyncio.AsyncioAuthenticator()
backend_auth.start(socket_addr="inproc://zap-backend")

Note:

- libzmq provides four levels of security: default NULL (which the Authenticator does
Expand Down Expand Up @@ -77,11 +93,22 @@ def __init__(
self.certs = {}
self.log = log or logging.getLogger('zmq.auth')

def start(self) -> None:
"""Create and bind the ZAP socket"""
def start(self, socket_addr="inproc://zeromq.zap.01") -> None:
"""Create and bind the ZAP socket

Parameters
----------
socket_addr : str, optional
The address to bind the ZAP socket to.
Default is "inproc://zeromq.zap.01"

.. versionadded:: 27.2
Support for custom socket addresses, enabling multiple
authenticators in the same process.
"""
self.zap_socket = self.context.socket(zmq.REP, socket_class=zmq.Socket)
self.zap_socket.linger = 1
self.zap_socket.bind("inproc://zeromq.zap.01")
self.zap_socket.bind(socket_addr)
self.log.debug("Starting")

def stop(self) -> None:
Expand Down
17 changes: 14 additions & 3 deletions zmq/auth/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,21 @@ def __init__(
self.pipe_endpoint = f"inproc://{id(self)}.inproc"
self.thread = None # type: ignore

def start(self) -> None:
"""Start the authentication thread"""
def start(self, socket_addr="inproc://zeromq.zap.01") -> None:
"""Start the authentication thread

Parameters
----------
socket_addr : str, optional
The address to bind the ZAP socket to.
Default is "inproc://zeromq.zap.01"

.. versionadded:: 27.2
Support for custom socket addresses, enabling multiple
authenticators in the same process.
"""
# start the Authenticator
super().start()
super().start(socket_addr)

# create a socket pair to communicate with auth thread.
self.pipe = self.context.socket(zmq.PAIR, socket_class=zmq.Socket)
Expand Down
Loading